Cara grep ps output dengan header


26

Bagaimana saya bisa mendapatkan output PS dengan header di tempat?

Dua proses ini membuat aplikasi yang berjalan di server saya ....

root     17123 16727  0 16:25 pts/6    00:00:00 grep GMC
root     32017     1 83 May03 ?        6-22:01:17 /scripts/GMC/PNetT-5.1-SP1/PNetTNetServer.bin -tempdir /usr/local/GMC/PNetT-5.1-SP1/tmpData -D

apakah itu 6-22:01:17berarti sudah berjalan selama 6 hari? Saya tring untuk menentukan berapa lama proses telah berjalan ...

Apakah kolom ke-2 id proses? Jadi jika saya melakukannya kill 32017akan mematikan proses ke-2?

Jawaban:


37
ps -ef | egrep "GMC|PID"

Ganti "GMC" dan psaktifkan sesuai kebutuhan.

Contoh output:

root@xxxxx:~$ ps -ef | egrep "disk|PID"

UID        PID  PPID  C STIME TTY          TIME CMD
paremh1  12501 12466  0 18:31 pts/1    00:00:00 egrep disk|PID
root     14936     1  0 Apr26 ?        00:02:11 /usr/lib/udisks/udisks-daemon
root     14937 14936  0 Apr26 ?        00:00:03 udisks-daemon: not polling any devices

8
Akan bagus untuk menambahkan beberapa info tentang 'mengapa' ini berfungsi.
Elijah Lynn

2
Tidak, itu latihan untuk pengguna.
Hyppy

@ElijahLynn Cocok dengan teks di header - dalam hal ini, PID. Tapi Anda bisa menukarnya dengan UID, PTIME, atau apa pun di header ...
Ben Creasy

5
Jadi ps -epilih semua proses, dan ps -fdaftar format lengkap yang menunjukkan tajuk kolom. Kemudian kita pipa header kolom dan output ke egrep, yang diperpanjang grep dan memungkinkan pipa |untuk memiliki arti khusus, yaitu ATAU (ini ATAU itu). Jadi, Anda akhirnya mencocokkan PID dalam tajuk kolom plus garis output yang penting.
Elijah Lynn

Saya harus menggunakan tanda kutip sederhana dalam perintah egrep / grep -E di Ubuntu 16.04, misalnya: ps -ef | grep -E 'GMC|PID'
Vlax

13

Terima kasih kepada geekosaur, saya ingin menggunakan perintah ini untuk permintaan Anda, daripada perintah yang terpisah:

ps -ef | head -1; ps -ef | grep "your-pattern-goes-here"

Kuncinya adalah memanfaatkan ";" didukung oleh shell untuk mem-chain perintah.


ini lebih bersih dan lebih kuat daripada jawaban yang diterima. Itu tidak menyatakan bahwa header memiliki PID di dalamnya dan tidak menambah kompleksitas ke string grep.
7yl4r

2
oh tunggu ... Anda sudah ps -efmengulanginya. lebih baik lagi adalahps -ef | { head -1 ; grep "your-pattern" ; }
7yl4r

@ 7yl4r tidak pernah menggunakan kemampuan shell itu. Saya mencoba perintah Anda yang ditingkatkan, bekerja dengan sempurna! Belajar, :)
Vic Lau

3
Ditemukan penjelasan tentang teknik ini, yang disebut 'Perintah Pengelompokan', untuk keingintahuan orang lain, lihat: gnu.org/software/bash/manual/html_node/Command-Grouping.html
Vic Lau

@ 7yl4r teknik hebat! Saya mencari cara untuk tidak mengulangi perintah. Perintah dikelompokkan bahkan bisa menjadi pipa: ps -ef | { head -1; grep "pattern" | head -5; }. Berguna jika pola grep-ed memiliki banyak hasil!
kecanduan

6

Kolom kedua adalah id proses; Keempat adalah ketika proses dibuat (biasanya ini adalah waktu program Anda dimulai, tetapi tidak selalu; pertimbangkan execve()dan teman-teman); 6 adalah jumlah waktu CPU yang dikonsumsi. Jadi sudah berjalan selama 8 hari dan menggunakan hampir 7 hari waktu CPU, yang saya anggap mengkhawatirkan.

Mendapatkan header dalam doa yang sama itu sulit di terbaik; Saya hanya akan melakukan yang terpisah ps | head -1. Anda dapat mempertimbangkan menggunakan psmetode pemilihan sendiri atau sesuatu seperti pgrepbukan grep, yang sebenarnya tidak dirancang untuk melewati tajuk.


Apa 83?
Webnet

Prioritas proses saat ini, yang didasarkan pada CPU sebelumnya dan penggunaan I / O dan nicenilai yang ditetapkan pengguna atau sistem . Angka yang lebih kecil adalah prioritas yang lebih tinggi. Dalam hal ini, grepadalah prioritas 0 karena diblokir pada disk membaca dan dihasilkan untuk menulis outputnya, dan PNetTNetServer.binmerupakan angka yang besar karena secara konsisten menggunakan timelice-nya tanpa memblokir. (Penjadwalan itu kompleks dan detailnya akan bergantung pada penjadwal yang tepat yang digunakan.)
geekosaur

5

Solusi egrep sederhana dan bermanfaat, tetapi tentu saja Anda bergantung pada header yang selalu berisi 'PID' (asumsi yang lebih masuk akal) dan string yang sama tidak muncul di tempat lain. Saya kira ini sudah cukup untuk kebutuhan Anda, tetapi kalau-kalau ada yang mau ada alternatif.

Sed memungkinkan Anda mengatakan "cetak baris pertama, lalu baris apa pun yang mengandung pola". Sebagai contoh:

ps auxwww | sed -n '1p; /PROCESS_NAME_TO_SEARCH/p;'

Tambahkan /sed -n/d;untuk memfilter sendiri:

ps auxwww | sed -n '1p; /sed -n/d; /PROCESS_NAME_TO_SEARCH/p;'

/sed -n/dtidak benar Beberapa perintah yang ada mungkin ada sed -n, yang ingin Anda cetak. Trik digunakan sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'. ;-) Catat di []sekitar karakter apa pun di string pencarian.
anishsane

4

alternatif yang lebih mudah: ps -ef | { head -1; grep GMC; }

ganti nomor dengan jumlah baris yang ditampilkan tajuk Anda.


1
Saya suka pendekatan ini tetapi perintah membutuhkan titik koma lain di akhir. ps -ef | { head -1; grep GMC; }. Saya juga menyukainya dalam fungsi seperti berikut:function pgrep() { ps -ef | { head -1; grep $@; } }
Brett

1

Anda bisa mendapatkan pid dengan pgrep

pgrep PNetTNetServer

dan kemudian gunakan ps dengan pid

ps u 12345

atau bahkan menggabungkan keduanya menjadi satu perintah

ps u `pgrep PNetTNetServer`

Ini akan menunjukkan hanya garis yang Anda inginkan, dan termasuk tajuk.


0

Saya menulis sebuah program Perl kecil yang akan dicetak

  • baris pertama dan semua baris yang cocok, jika ada yang cocok, atau
  • tidak ada, jika tidak ada yang cocok.

Saya paling sering menggunakannya ps | 1andre GMC, tetapi bisa juga mengambil argumen file (setiap file menyediakan baris header sendiri untuk pertandingan yang dibuat pada baris dari file itu).



#!/usr/bin/perl

#
# 1andre <regexp> [<file> ...]
#
#   1 -           first ({1}st)
# and -                  {and}
#  re - (lines matching) {re}gexp
#
# If no <files> are given (or "-" is given as a <file>) stdin is
# used.
#
# If any lines from each <file> match the <regexp>, print the
# first line from that <file> and all the matching lines from
# that <file>.
#

use strict;
use warnings;

if(scalar @ARGV < 1) {
  printf STDERR "usage: %s <regexp> [<file> ...]\n", $0;
  exit 1;
}

my $re = shift;
my $header;

while(<>) {
  if($. == 1) {
    $header = $_;
  } elsif(m/$re/) {
    if(defined $header) {
      print $header;
      undef $header;
    }
    print;
  }
} continue {
  # close resets $. when we get to the end of each file that <> is processing
  close ARGV if eof;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.