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:
sed -e '1p' -e '/youpattern/!d'
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 -eopsi. 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 pperintah yang biasanya mencetak semua baris. Tapi kami menambahkannya dengan nilai numerik yang menentukan rentang yang harus diterapkan. Di sini, kami menggunakan 1yang berarti baris pertama. Jika Anda ingin mencetak lebih banyak baris, Anda dapat menggunakan di x,ypmana xbaris pertama untuk dicetak, yadalah baris terakhir untuk mencetak. Misalnya untuk mencetak 3 baris pertama, Anda akan menggunakan1,3p
Perintah selanjutnya adalah dyang biasanya menghapus semua baris dari buffer. Sebelum perintah ini kita menempatkan yourpatternantara dua /karakter. Ini adalah cara lain (pertama adalah untuk menentukan baris mana seperti yang kita lakukan dengan pperintah) dari pengalamatan baris yang harus dijalankan oleh perintah. Ini berarti perintah hanya akan bekerja untuk garis yang cocok yourpattern. Kecuali, kita menggunakan !karakter sebelum dperintah 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 pperintah dan sekali karena kecocokan). Kita dapat menghindari ini dengan dua cara:
Menambahkan 1dperintah setelah 1p. Seperti yang telah saya sebutkan, dperintah 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 1bperintah, alih-alih 1p. Itu tipuan. bperintah 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, dperintah terakhir tidak akan menghapus baris ini dari buffer.
Contoh lengkap:
ps aux | sed -e '1b' -e '/syslog/!d'
Menggunakan titik koma
Beberapa sedimplementasi dapat menghemat Anda mengetik dengan menggunakan titik koma untuk memisahkan perintah daripada menggunakan beberapa -eopsi. Jadi jika Anda tidak peduli tentang menjadi portabel perintahnya akan ps aux | sed '1b;/syslog/!d'. Ini berfungsi setidaknya dalam GNU seddan busyboximplementasi.
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:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog'
Bagaimana itu bekerja
Pertama, kami menggunakan -nopsi 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 dengan 1:(baris pertama) atau berisi pola kami (dalam hal ini adalah syslog).
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:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog' | cut -d ':' -f2-
-dopsi menentukan pembatas, -fmenentukan 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.
acksangat berguna, dan mengapaperlmeroket masa lalused,awkdll dalam popularitas: penting untuk bagian-bagian untuk meringkas menjadi satu kesatuan yang koheren.