Dengan asumsi grep sederhana seperti:
$ psa aux | grep someApp
1000 11634 51.2 0.1 32824 9112 pts/1 SN+ 13:24 7:49 someApp
Ini memberikan banyak informasi, tetapi karena baris pertama dari perintah ps tidak ada, tidak ada konteks untuk info tersebut. Saya lebih suka bahwa baris pertama ps ditampilkan juga:
$ psa aux | someMagic someApp
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
1000 11634 51.2 0.1 32824 9112 pts/1 SN+ 13:24 7:49 someApp
Tentu saja, saya bisa menambahkan regex ke grep khusus untuk ps:
$ ps aux | grep -E "COMMAND|someApp"
Namun, saya lebih suka solusi yang lebih umum karena ada kasus lain di mana saya ingin memiliki baris pertama juga.
Sepertinya ini akan menjadi kasus penggunaan yang baik untuk deskriptor file "stdmeta" .
bash
command-line
dotancohen
sumber
sumber
ack
sangat berguna, dan mengapaperl
meroket masa lalused
,awk
dll dalam popularitas: penting untuk bagian-bagian untuk meringkas menjadi satu kesatuan yang koheren.-C
argumen untukps
dan Anda tidak perlu memasukkannya ke grep. misalnyaps u -C someApp
atau bahkanps u -C app1 -C app2 -C app3
ps aux | { head -1; grep foo; }
disebutkan oleh @Nahuel Fouilleul di bawah ini (mungkin ini satu-satunya solusi yang bisa saya ingat di tempat jika diperlukan)Jawaban:
Cara yang baik
Biasanya Anda tidak dapat melakukan ini dengan grep tetapi Anda dapat menggunakan alat lain. AWK sudah disebutkan tetapi Anda juga dapat menggunakan
sed
, seperti ini:Bagaimana itu bekerja:
Utilitas sed bekerja pada setiap baris secara individual, menjalankan perintah yang ditentukan pada masing-masing baris Anda dapat memiliki banyak perintah, menentukan beberapa
-e
opsi. Kami dapat menambahkan setiap perintah dengan parameter rentang yang menentukan apakah perintah ini harus diterapkan ke baris tertentu atau tidak."1p" adalah perintah pertama. Ini menggunakan
p
perintah yang biasanya mencetak semua baris. Tapi kami menambahkannya dengan nilai numerik yang menentukan rentang yang harus diterapkan. Di sini, kami menggunakan1
yang berarti baris pertama. Jika Anda ingin mencetak lebih banyak baris, Anda dapat menggunakan dix,yp
manax
baris pertama untuk dicetak,y
adalah baris terakhir untuk mencetak. Misalnya untuk mencetak 3 baris pertama, Anda akan menggunakan1,3p
Perintah selanjutnya adalah
d
yang biasanya menghapus semua baris dari buffer. Sebelum perintah ini kita menempatkanyourpattern
antara dua/
karakter. Ini adalah cara lain (pertama adalah untuk menentukan baris mana seperti yang kita lakukan denganp
perintah) dari pengalamatan baris yang harus dijalankan oleh perintah. Ini berarti perintah hanya akan bekerja untuk garis yang cocokyourpattern
. Kecuali, kita menggunakan!
karakter sebelumd
perintah yang membalikkan logikanya. Jadi sekarang akan menghapus semua garis yang tidak cocok dengan pola yang ditentukan.Pada akhirnya, sed akan mencetak semua garis yang tersisa di buffer. Tapi kami menghapus garis yang tidak cocok dari buffer sehingga hanya garis yang cocok yang akan dicetak.
Singkatnya: kami mencetak baris ke-1, lalu kami menghapus semua baris yang tidak cocok dengan pola kami dari input. Sisa baris dicetak (sehingga hanya baris yang melakukan sesuai pola).
Masalah lini pertama
Seperti yang disebutkan dalam komentar, ada masalah dengan pendekatan ini. Jika pola yang ditentukan cocok dengan baris pertama, maka akan dicetak dua kali (sekali dengan
p
perintah dan sekali karena kecocokan). Kita dapat menghindari ini dengan dua cara:Menambahkan
1d
perintah setelah1p
. Seperti yang telah saya sebutkan,d
perintah menghapus baris dari buffer dan kami menentukan rentangnya dengan nomor 1, yang berarti hanya akan menghapus baris ke-1. Jadi perintahnya adalahsed -e '1p' -e '1d' -e '/youpattern/!d'
Menggunakan
1b
perintah, alih-alih1p
. Itu tipuan.b
perintah memungkinkan kita untuk beralih ke perintah lain yang ditentukan oleh label (dengan cara ini beberapa perintah dapat dihilangkan). Tetapi jika label ini tidak ditentukan (seperti dalam contoh kita) itu hanya melompat ke akhir perintah, mengabaikan sisa perintah untuk baris kita. Jadi dalam kasus kami,d
perintah terakhir tidak akan menghapus baris ini dari buffer.Contoh lengkap:
Menggunakan titik koma
Beberapa
sed
implementasi dapat menghemat Anda mengetik dengan menggunakan titik koma untuk memisahkan perintah daripada menggunakan beberapa-e
opsi. Jadi jika Anda tidak peduli tentang menjadi portabel perintahnya akanps aux | sed '1b;/syslog/!d'
. Ini berfungsi setidaknya dalamGNU sed
danbusybox
implementasi.Cara yang gila
Namun, inilah cara yang agak gila untuk melakukan ini dengan grep. Jelas tidak optimal, saya memposting ini hanya untuk tujuan belajar, tetapi Anda dapat menggunakannya misalnya, jika Anda tidak memiliki alat lain di sistem Anda:
Bagaimana itu bekerja
Pertama, kami menggunakan
-n
opsi untuk menambahkan nomor baris sebelum setiap baris. Kami ingin menghitung semua baris yang kami cocokkan.*
- apa pun, bahkan baris kosong. Seperti yang disarankan dalam komentar, kami juga dapat mencocokkan '^', hasilnya sama.Kemudian kami menggunakan ekspresi reguler yang diperluas sehingga kami dapat menggunakan
\|
karakter khusus yang berfungsi sebagai OR. Jadi kami cocok jika garis dimulai dengan1:
(baris pertama) atau berisi pola kami (dalam hal ini adalahsyslog
).Masalah nomor baris
Sekarang masalahnya adalah, kita mendapatkan nomor garis jelek ini di output kita. Jika ini merupakan masalah, kami dapat menghapusnya dengan
cut
, seperti ini:-d
opsi menentukan pembatas,-f
menentukan bidang (atau kolom) yang ingin kita cetak. Jadi kami ingin memotong setiap baris pada setiap:
karakter dan hanya mencetak 2 dan semua kolom berikutnya. Ini secara efektif menghapus kolom pertama dengan pembatasnya dan inilah yang kita butuhkan.sumber
cat -n
baik dan akan terlihat lebih jelas karena grep disalahgunakan untuk ini.nl
tidak menghitung garis kosong (tetapi mencetaknya tanpa nomor garis),cat -n
memformat penomoran dengan spasi sebelumnya,grep -n .
menghapus garis kosong sama sekali dan menambahkan tanda titik dua. Semua memiliki ... eh ... fitur ;-)ps aux | sed '1p;/pattern/!d'
akan mencetak baris pertama dua kali jika cocok dengan pola . Terbaik adalah dengan menggunakanb
perintah:ps aux | sed -e 1b -e '/pattern/!d'
.cat -n
bukan POSIX.grep -n '^'
akan memberi nomor setiap baris (bukan masalah untuk output ps yang tidak memiliki baris kosong).nl -ba -d $'\n'
angka setiap baris.1b;...
tidak portabel atau POSIX, tidak ada perintah lain setelah "b", jadi Anda perlu baris baru atau ekspresi -e lainnya.Bagaimana perasaan Anda tentang menggunakan
awk
bukangrep
?NR == 1
: Jumlah record == 1; yaitu. baris pertama||
: atau:/syslogd/
: Pola untuk dicariMungkin juga layak untuk dilihat
pgrep
, meskipun ini lebih untuk skrip daripada output yang dihadapi pengguna. Itu menghindarigrep
perintah itu sendiri muncul di output, meskipun.sumber
Sunting: setelah komentar
Saya meskipun
head -1
akan membaca semua input, tetapi setelah mengujinya, ia bekerja juga.output adalah
sumber
{ IFS='' read line; ... }
kalau-kalau header dimulai dengan spasi.head -1
alih-alih membaca / gema.head -n1
pada bash saya. Ini mungkin spesifik implementasi. Kepala saya tidak membaca seluruh input dalam hal ini, hanya baris pertama, meninggalkan sisanya di buffer input.head -n1
lebih pendek, tetapi muncul bahkan spec POSIX diam untuk berapa banyak inputnya diizinkan untuk membaca, jadi mungkinread line; echo $line
lebih portabel setelah semua.Ps mendukung filter internal,
Misalkan Anda mencari proses bash:
ps -C bash -f
Akan mencantumkan semua proses yang bernama
bash
.sumber
Saya cenderung mengirim tajuk ke stderr :
Ini biasanya cukup untuk keperluan membaca manusia. misalnya:
Bagian yang dikurung bisa masuk ke skrip sendiri untuk penggunaan umum.
Ada kenyamanan tambahan bahwa output dapat disalurkan lebih lanjut (ke
sort
dll.) Dan header akan tetap di atas.sumber
Anda juga bisa menggunakan
tee
danhead
:Namun perlu dicatat bahwa selama
tee
tidak dapat mengabaikanSIGPIPE
sinyal (lihat misalnya diskusi di sini ), pendekatan ini membutuhkan solusi yang dapat diandalkan. Solusinya adalah dengan mengabaikan sinyal SIGPIPE, ini misalnya dapat dilakukan seperti ini di shell seperti bash:Perhatikan juga bahwa urutan output tidak dijamin .
sumber
grep
:| { sleep .5; cat }
.Mungkin dua
ps
perintah akan lebih mudah.sumber
ps aux
panggilan pertama dan kedua ... Dan jika Anda hanya ingin baris pertama yang statis, mengapa tidak mengulanginya secara manual?Anda bisa menggunakan pidstat dengan:
Contoh:
Info Lebih Lanjut: http://linux.die.net/man/1/pidstat
sumber
Masukkan yang berikut ini di file .bashrc Anda atau salin / tempel ke dalam shell terlebih dahulu, untuk pengujian.
Penggunaan: psls [pola grep]
Pastikan untuk mencari .bashrc Anda (atau .bash_profile jika Anda meletakkannya di sana):
Fungsi ini bahkan akan selesai secara otomatis pada baris perintah shell. Seperti yang Anda nyatakan dalam jawaban lain, Anda bisa menyalurkan baris pertama ke file untuk menyimpan satu panggilan ke ps.
sumber
psl
, yang hanya memanggilps
dangrep
sekali saja (dan tidak perluhead
).urutkan tetapi pertahankan baris tajuk di bagian atas
Dan gunakan seperti ini
sumber
Terima kasih banyak kepada Janis Papanagnou di comp.unix.shell, saya menggunakan fungsi berikut:
Ini memiliki sejumlah keunggulan:
-i
untuk pencocokan case-sensitive,-E
untuk regex yang diperluas, dll.Contoh penggunaan:
sumber
Cara lain dengan
gnu ed
:atau, jika shell mendukung substitusi proses:
itu adalah:
Lebih portabel, tanpa
gnu
'!'
atau substitusi shell - hanya menggunakaned
built-inr
untukr
menghasilkan outputps aux
ke buffer dan kemudian menghapus garis yang tidak cocok dalam2,$
kisaran dan mencetak hasilnya:Dan karena
sed
perintah dalam jawaban yang diterima output juga baris yang cocok dengan diri mereka sendiri, dengansed
yang mendukung-f-
dan shell yang mendukung proses substitusi saya akan menjalankan:yang cukup banyak melakukan hal yang sama dengan
ed
perintah sebelumnya .sumber
Cara Perl:
Cara membaca lebih mudah daripada
sed
, lebih cepat, tidak ada risiko untuk memilih kalimat yang tidak diinginkan.sumber
Jika itu hanya untuk proses grepping dengan header penuh, saya akan memperluas saran @ mrb:
pgrep bash | xargs ps -fp
akan mendapatkan hasil yang sama tetapi tanpa subkulit. Jika pemformatan lain diperlukan:sumber
Jika Anda tahu angka garis pastinya, mudah dengan perl! Jika Anda ingin mendapatkan baris 1 dan 5 dari file, katakan / etc / passwd:
Jika Anda ingin mendapatkan baris lain juga, cukup tambahkan angka mereka di array.
sumber