GNU/Linux >> Belajar Linux >  >> Linux

10 Contoh Perintah Grep Praktis untuk Pengembang

Baru-baru ini, saya mulai bekerja dengan Asciidoctor.js dan on proyek Asciidoctor.js-pug dan Asciidoctor-templates.js.

Tidak selalu mudah untuk langsung efektif ketika Anda pertama kali menggali basis kode yang berisi beberapa ribu baris. Tapi senjata rahasia saya untuk menemukan jalan saya melalui begitu banyak baris kode adalah grep alat.

Saya akan berbagi dengan Anda cara menggunakan perintah grep di Linux dengan contoh.

Contoh nyata yang berguna dari perintah grep di Linux

Jika Anda melihat ke man , Anda akan melihat deskripsi singkat untuk grep alat:“cetak garis yang cocok dengan pola”.

Namun, jangan tertipu oleh definisi sederhana seperti ini:grep adalah salah satu alat yang paling berguna di kotak alat Unix dan ada banyak kesempatan untuk menggunakannya segera setelah Anda bekerja dengan file teks.

Itu selalu lebih baik untuk memiliki contoh dunia nyata untuk mempelajari cara kerja sesuatu. Jadi, saya akan menggunakan pohon sumber Asciidoctor.js untuk mengilustrasikan beberapa grep kemampuan.

Anda dapat mengunduh pohon sumber itu dari GitHub, dan jika Anda mau, Anda bahkan dapat melihat perubahan yang sama yang saya gunakan saat menulis artikel ini. Itu akan memastikan Anda mendapatkan hasil yang sangat identik dengan yang dijelaskan di sisa artikel ini:

git clone https://github.com/asciidoctor/asciidoctor.js
cd asciidoctor.js
git checkout v1.5.6-rc.1

1. Temukan semua kemunculan string (penggunaan dasar)

Asciidoctor.js mendukung mesin JavaScript Nashorn untuk platform Java. Saya tidak tahu Nashorn, jadi saya dapat mengambil kesempatan itu untuk mempelajari lebih lanjut tentangnya dengan menjelajahi bagian-bagian proyek yang merujuk pada mesin JavaScript itu.

Sebagai titik awal, saya memeriksa apakah ada beberapa pengaturan yang terkait dengan Nashorn di package.json file yang menjelaskan dependensi proyek:

[email protected]:~$ grep nashorn package.json
    "test": "node npm/test/builder.js && node npm/test/unsupported-features.js && node npm/test/jasmine-browser.js && node npm/test/jasmine-browser-min.js && node npm/test/jasmine-node.js && node npm/test/jasmine-webpack.js && npm run test:karmaBrowserify && npm run test:karmaRequirejs && node npm/test/nashorn.js",

Ya, ternyata ada beberapa tes khusus Nashorn. Jadi, mari kita selidiki lebih jauh.

2. Pencarian peka huruf besar/kecil dalam kumpulan file

Sekarang, saya ingin melihat lebih dekat file dari ./npm/test/ direktori yang menyebutkan secara eksplisit Nashorn.

Pencarian peka huruf besar/kecil (-i option) mungkin lebih baik di sini karena saya perlu menemukan kedua referensi ke nashorn dan Nashorn (atau kombinasi karakter huruf besar dan kecil lainnya):

[email protected]:~$ grep -i nashorn npm/test/*.js
npm/test/nashorn.js:const nashornModule = require('../module/nashorn');
npm/test/nashorn.js:log.task('Nashorn');
npm/test/nashorn.js:nashornModule.nashornRun('jdk1.8.0');

Memang, ketidakpekaan huruf besar-kecil berguna di sini. Jika tidak, saya akan melewatkan require('../module/nashorn') penyataan. Tidak diragukan lagi saya harus memeriksa file itu secara lebih rinci nanti.

3. Temukan semua file yang tidak cocok

Omong-omong, apakah ada beberapa file khusus non-Nashorm di npm/test/ direktori? Untuk menjawab pertanyaan tersebut, kita dapat menggunakan opsi “print non-matching files” dari grep (-L pilihan):

sh$ grep -iL nashorn npm/test/*
npm/test/builder.js
npm/test/jasmine-browser-min.js
npm/test/jasmine-browser.js
npm/test/jasmine-node.js
npm/test/jasmine-webpack.js
npm/test/unsupported-features.js

Perhatikan caranya dengan -L pilihan output dari grep telah berubah untuk hanya menampilkan nama file. Jadi, tidak ada file di atas yang mengandung string "nashorn" (terlepas dari kasusnya). Itu tidak berarti mereka entah bagaimana tidak terkait dengan teknologi itu, tapi setidaknya, huruf "n-a-s-h-o-r-n" tidak ada.

4. Menemukan pola ke dalam file tersembunyi dan secara rekursif ke dalam sub-direktori

Dua perintah terakhir menggunakan pola glob shell untuk meneruskan daftar file yang akan diperiksa ke grep memerintah.

Namun, ini memiliki beberapa batasan bawaan:bintang (* ) tidak akan cocok dengan file tersembunyi. Juga tidak akan cocok dengan file (akhirnya) yang terdapat dalam sub-direktori.

Solusinya adalah menggabungkan grep dengan perintah find alih-alih mengandalkan pola glob shell:

# This is not efficient as it will spawn a new grep process for each file
[email protected]:~$ find npm/test/ -type f -exec grep -iL nashorn \{} \;
# This may have issues with filenames containing space-like characters
[email protected]:~$ grep -iL nashorn $(find npm/test/ -type f)

Seperti yang saya sebutkan sebagai komentar di blok kode di atas, masing-masing solusi ini memiliki kekurangan.

Mengenai nama file yang mengandung karakter seperti spasi, saya mengizinkan Anda menyelidiki grep -z opsi yang, dikombinasikan dengan -print0 opsi find perintah, dapat mengurangi masalah itu. Jangan ragu untuk menggunakan bagian komentar di akhir artikel ini untuk membagikan ide Anda tentang topik tersebut!

Namun demikian, solusi yang lebih baik akan menggunakan "rekursif" (-r ) opsi grep . Dengan opsi itu, Anda memberikan pada baris perintah akar pohon pencarian Anda (direktori awal) alih-alih daftar nama file eksplisit untuk diperiksa.

Dengan -r opsi, grep akan mencari semua file di direktori yang ditentukan, termasuk yang tersembunyi, dan kemudian secara rekursif akan turun ke sub-direktori apa pun:

[email protected]:~$ grep -irL nashorn npm/test/npm/
npm/test/builder.js
npm/test/jasmine-browser-min.js
npm/test/jasmine-browser.js
npm/test/jasmine-node.js
npm/test/jasmine-webpack.js
npm/test/unsupported-features.js

Sebenarnya, dengan opsi itu, saya juga bisa memulai eksplorasi saya satu tingkat di atas untuk melihat ada tes non-npm yang menargetkan Nashorn juga:

[email protected]:~$ grep -irL nashorn npm/

Saya membiarkan Anda menguji perintah itu sendiri untuk melihat hasilnya; tetapi sebagai petunjuk, saya dapat mengatakan Anda harus menemukan lebih banyak file yang cocok!

5. Memfilter file berdasarkan namanya (menggunakan ekspresi reguler)

Jadi, sepertinya ada beberapa tes khusus Nashorn dalam proyek itu. Karena Nashorn adalah Java, pertanyaan lain yang dapat diajukan adalah “Apakah ada beberapa file sumber Java dalam proyek yang secara eksplisit menyebutkan Nashorn?” .

Tergantung pada versi grep Anda gunakan, setidaknya ada dua solusi untuk menjawab pertanyaan itu.

Yang pertama adalah menggunakan grep untuk menemukan semua file yang berisi pola “nashorn”, lalu pipa output dari perintah pertama itu ke grep kedua contoh memfilter file sumber non-java:

[email protected]:~$ grep -ir nashorn ./ | grep "^[^:]*\.java"
./spec/nashorn/AsciidoctorConvertWithNashorn.java:public class AsciidoctorConvertWithNashorn {
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/asciidoctor-convert.js"));
./spec/nashorn/BasicJavascriptWithNashorn.java:public class BasicJavascriptWithNashorn {
./spec/nashorn/BasicJavascriptWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/BasicJavascriptWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/basic.js"));

Bagian pertama dari perintah seharusnya sudah bisa dimengerti sekarang. Tapi bagaimana dengan bagian “^[\^:]*\\.java” itu?

Kecuali Anda menentukan -F opsi, grep mengasumsikan pola pencarian adalah ekspresi reguler. Itu berarti, selain karakter biasa yang akan cocok dengan kata demi kata, Anda memiliki akses ke satu set metakarakter untuk menggambarkan pola yang lebih kompleks. Pola yang saya gunakan di atas hanya akan cocok:

  • ^ awal baris
  • [^:]* diikuti oleh urutan karakter apa pun kecuali titik dua
  • \. diikuti oleh titik (titik memiliki arti khusus dalam regex , jadi saya harus melindunginya dengan garis miring terbalik untuk menyatakan bahwa saya menginginkan kecocokan literal)
  • java dan diikuti oleh empat huruf “java”.

Dalam praktiknya, sejak grep akan menggunakan titik dua untuk memisahkan nama file dari konteksnya, saya hanya menyimpan baris yang memiliki .java di bagian nama file. Layak untuk disebutkan akan cocokkan juga .javascript nama file. Ini adalah sesuatu yang saya biarkan coba selesaikan sendiri jika Anda mau.

6. Memfilter file berdasarkan namanya menggunakan grep

Ekspresi reguler sangat kuat. Namun, dalam kasus tertentu, tampaknya berlebihan. Tanpa menyebutkan solusi di atas, kami menghabiskan waktu memeriksa semua file untuk mencari pola “nashorn”— sebagian besar hasil dibuang oleh langkah kedua dari pipeline.

Jika Anda menggunakan grep versi GNU , sesuatu yang mungkin jika Anda menggunakan Linux, Anda memiliki solusi lain dengan --include pilihan. Ini menginstruksikan grep untuk hanya mencari file yang namanya cocok dengan pola glob yang diberikan:

[email protected]:~$ grep -ir nashorn ./ --include='*.java'
./spec/nashorn/AsciidoctorConvertWithNashorn.java:public class AsciidoctorConvertWithNashorn {
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/asciidoctor-convert.js"));
./spec/nashorn/BasicJavascriptWithNashorn.java:public class BasicJavascriptWithNashorn {
./spec/nashorn/BasicJavascriptWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/BasicJavascriptWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/basic.js"));

7. Menemukan kata

Hal yang menarik tentang proyek Asciidoctor.js adalah proyek multi-bahasa. Pada intinya, Asciidoctor ditulis dalam Ruby, jadi, agar dapat digunakan di dunia JavaScript, Asciidoctor harus "ditranspilasikan" menggunakan Opal, kompiler sumber-ke-sumber Ruby ke JavaScript. Teknologi lain yang tidak saya ketahui sebelumnya.

Jadi, setelah memeriksa kekhususan Nashorn, saya menugaskan kepada diri saya sendiri tugas untuk lebih memahami API Opal. Sebagai langkah pertama dalam pencarian itu, saya mencari semua penyebutan Opal objek global dalam file JavaScript proyek. Itu bisa muncul di kepura-puraan (Opal = ), akses anggota (Opal. ) atau bahkan mungkin dalam konteks lain. Ekspresi reguler akan berhasil. Namun, sekali lagi, grep memiliki beberapa solusi yang lebih ringan untuk menyelesaikan kasus penggunaan umum itu. Menggunakan -w opsi, itu hanya akan cocok dengan kata , yaitu pola yang didahului dan diikuti oleh karakter bukan kata. Karakter bukan kata adalah awal baris, akhir baris, atau karakter apa pun yang bukan huruf, angka, atau garis bawah:

[email protected]:~$ grep -irw --include='*.js' Opal .
...

8. mewarnai output

Saya tidak menyalin output dari perintah sebelumnya karena ada banyak kecocokan. Ketika output padat seperti itu, Anda mungkin ingin menambahkan sedikit warna untuk memudahkan pemahaman. Jika ini belum dikonfigurasi secara default pada sistem Anda, Anda dapat mengaktifkan fitur tersebut menggunakan --color GNU pilihan:

[email protected]:~$ grep -irw --color=auto --include='*.js' Opal .
...

Anda seharusnya mendapatkan hasil panjang yang sama seperti sebelumnya, tetapi kali ini string pencarian akan muncul dalam warna jika belum demikian.

9. Menghitung baris yang cocok atau file yang cocok

Saya sebutkan dua kali output dari perintah sebelumnya sangat panjang. Berapa lama tepatnya?

[email protected]:~$ grep -irw --include='*.js' Opal . | wc -l
86

Itu berarti kita memiliki total 86 baris yang cocok di semua file yang diperiksa. Namun, berapa banyak file berbeda yang cocok? Dengan -l opsi Anda dapat membatasi grep keluarkan file yang cocok alih-alih menampilkan baris yang cocok . Jadi perubahan sederhana itu akan memberi tahu berapa banyak file yang cocok:

[email protected]:~$ grep -irwl --include='*.js' Opal . | wc -l
20

Jika itu mengingatkan Anda pada -L opsi, tidak mengherankan:karena relatif umum, huruf kecil/huruf besar digunakan untuk membedakan opsi pelengkap. -l menampilkan nama file yang cocok. -L menampilkan nama file yang tidak cocok. Untuk contoh lain, saya membiarkan Anda memeriksa manual untuk -h /-H pilihan.

Mari kita tutup tanda kurung itu dan kembali ke hasil kita:86 garis yang cocok. 20 file yang cocok. Namun, bagaimana mendistribusikan baris yang cocok dalam file matching yang cocok ? Kita dapat mengetahuinya dengan menggunakan -c pilihan grep yang akan menghitung jumlah baris yang cocok per file yang diperiksa (termasuk file dengan nol kecocokan):

[email protected]:~$ grep -irwc --include='*.js' Opal .
...

Seringkali, keluaran tersebut memerlukan beberapa pasca-pemrosesan karena ia menampilkan hasilnya sesuai urutan file yang diperiksa, dan juga menyertakan file tanpa kecocokan— sesuatu yang biasanya tidak menarik bagi kita. Yang terakhir ini cukup mudah untuk dipecahkan:

[email protected]:~$ grep -irwc --include='*.js' Opal . | grep -v ':0$'

Untuk memesan sesuatu, Anda dapat menambahkan perintah sort di akhir pipeline:

[email protected]:~$ grep -irwc --include='*.js' Opal . | grep -v ':0$' | sort -t: -k2n

Saya membiarkan Anda memeriksa sort perintah manual untuk arti yang tepat dari opsi yang saya gunakan. Jangan lupa untuk membagikan temuan Anda menggunakan bagian komentar di bawah!

10. Menemukan perbedaan antara dua set yang cocok

Jika Anda ingat, beberapa perintah yang lalu, saya mencari kata "Opal." Namun, jika saya mencari di kumpulan file yang sama untuk semua kemunculan string “Opal,” saya mendapatkan sekitar dua puluh jawaban lagi:

[email protected]:~$ grep -irw --include='*.js' Opal . | wc -l
86
[email protected]:~$ grep -ir --include='*.js' Opal . | wc -l
105

Menemukan perbedaan antara dua set itu akan menarik. Jadi, apa sajakah baris yang memuat empat huruf “opal” secara berurutan, tetapi di mana keempat huruf tersebut tidak membentuk satu kata?

Ini tidak mudah untuk menjawab pertanyaan itu. Karena sama baris dapat berisi keduanya kata Opal serta beberapa kata yang lebih besar yang mengandung keempat huruf itu. Tetapi sebagai perkiraan pertama, Anda dapat menggunakan saluran itu:

[email protected]:~$ grep -ir --include='*.js' Opal . | grep -ivw Opal
./npm/examples.js:  const opalBuilder = OpalBuilder.create();
./npm/examples.js:  opalBuilder.appendPaths('build/asciidoctor/lib');
./npm/examples.js:  opalBuilder.appendPaths('lib');
...

Rupanya, pemberhentian saya berikutnya adalah menyelidiki opalBuilder keberatan, tapi itu untuk hari lain.

Kata terakhir

Tentu saja, Anda tidak akan memahami organisasi proyek, apalagi arsitektur kode, hanya dengan mengeluarkan beberapa grep perintah!

Namun, saya menemukan perintah itu tidak dapat dihindari untuk mengidentifikasi tolok ukur dan titik awal saat menjelajahi basis kode baru.

Jadi, saya harap artikel ini membantu Anda memahami kekuatan grep perintah dan Anda akan menambahkannya ke peti alat Anda. Tidak diragukan lagi Anda tidak akan menyesalinya!


Linux
  1. 8 Contoh Praktis Perintah Linux Xargs untuk Pemula

  2. Contoh Perintah DNF Untuk Pemula

  3. 10 Contoh Praktis Menggunakan Perintah scp

  1. Perintah cp di Linux:7 Contoh Praktis

  2. Perintah Shutdown Linux:5 Contoh Praktis

  3. Perintah nslookup:7 Contoh Praktis

  1. 14 Contoh Perintah Grep di Linux

  2. 12 Contoh Perintah IP untuk Pengguna Linux

  3. 16 Contoh Praktis perintah LS Linux untuk Pemula