Perintah Shell untuk menemukan file yang mengandung satu kata tetapi bukan kata kedua


5

Semua

Saya memiliki dua file di bawah ini di mesin linux saya dan saya ingin mencari tahu file yang berisi "word1" dan tidak mengandung "word99"

file1.txt
  word1
  word2
  word3
  word4
  word5

file2.txt
  word1
  word2
  word3
  word99

Saya telah menggunakan perintah di bawah ini untuk file termasuk "word1", tetapi tidak dapat menemukan informasi tentang cara memodifikasinya untuk mendapatkan nama file yang mengandung "word1" tetapi tidak "word99"

find . -name '*.*' -exec grep -r 'word1' {} \; -print > output.txt

Petunjuk apa pun akan sangat membantu.

Terima kasih, Sandy

Jawaban:


5
    $ grep -lr 'word1' * | xargs grep -L 'word99'
    file1.txt

dimana:

    -l, --files-with-matches
         Only the names of files containing selected lines are written
         to standard output.
    -R, -r, --recursive
         Recursively search subdirectories listed.
    -L, --files-without-match
         Only the names of files not containing selected lines are written
         to standard output.

Di bagian pertama dari perintah sebelum pipa, kita mendapatkan:

    $ grep -lr 'word1' * 
    file1.txt
    file2.txt

Perintah di atas secara rekursif mem-parsing file di dalam subdirektori dan daftar file yang berisi kata word1, yaitu file1.txtdan file2.txt.

Kemudian di bagian kedua | xargs grep -L 'word99', pipa mengirim file1.txtdan file2.txtsebagai input xargsyang menyediakannya grepsebagai argumen. grepkemudian mencantumkan file yang tidak mengandung word99menggunakan -Lopsi, yaitu file1.txt.

Kita perlu di xargssini karena di bagian pertama dari perintah, kita dapatkan file1.txtdan file2.txtsebagai output pada stdout. Kita perlu mengurai isi dari file-file ini dan bukan string file1.txtdan file2.txt.

Perintah berikut ini juga memberikan hasil yang sama (membalikkan cara kita mencari / mengecualikan string):

      $ grep -Lr 'word99' * | xargs grep -l 'word1'
      file1.txt

1
grep -r … *hampir selalu lebih baik ditulis grep -r … .. Versi asterisk menjadi jelek jika ada terlalu banyak file di direktori saat ini, dll.
Eric

0

Ini menemukan file yang mengandung word1:

$ find . -name '*.*' -type f -exec grep -q 'word1' {} \; -print
./file1.txt
./file2.txt

Ini menemukan file yang mengandung word1tetapi tidak word99 :

$ find . -name '*.*' -type f -exec grep -q 'word1' {} \; '!' -exec grep -q 'word99' {} \; -print 
./file1.txt

Untuk menyimpan hasil dalam file:

find . -name '*.*' -type f -exec grep -q 'word1' {} \; '!' -exec grep -q 'word99' {} \; -print >output.txt

Tes -exec grep -q word99 {} \;mengembalikan True untuk file dengan word99. Kami meletakkannya !di depan untuk meniadakan nilai kembali. Jadi, ! -exec grep -q word99 {} \;mengembalikan True untuk file yang tidak memiliki word99. Ini !dalam tanda kutip tunggal karena, jika ekspansi sejarah dihidupkan, !bisa menjadi karakter shell-aktif.

Catatan:

  1. The -qpilihan yang ditambahkan untuk grepmembuatnya tenang. Dengan -q, grep akan menetapkan kode keluar yang benar tetapi tidak menampilkan garis yang cocok pada stdout.

  2. The -type fuji ditambahkan ke findsehingga hanya mengembalikan nama file biasa.


Terima kasih John atas jawabannya, tetapi bagaimana jika saya harus melakukan pencarian di semua folder (rekursif). Cuaca hanya menambahkan "-r" bekerja?
Sandeep K Gujje

@SandeepKGujje find, sendiri, melakukan pencarian rekursif pada semua folder.
John1024

0

Judul pertanyaan Anda mengatakan "file yang mengandung" sebuah kata. Namun, dalam pertanyaan Anda, Anda menyebutkan "dapatkan nama file yang mengandung" sebuah kata. Ini adalah hal yang berbeda. Untungnya, keduanya agak sederhana, jadi saya hanya akan menunjukkan kepada Anda berdua.

Untuk menemukan file yang mengandung kata:

grep -iR "word1".

-I mengatakan untuk mengabaikan kasus. -R bersifat rekursif (artinya subdirektori dicari). (Huruf kapital didokumentasikan oleh OpenBSD dan lebih mirip dengan ls, jadi saya lebih suka over -r.) Periode menentukan tempat untuk mulai mencari.

Untuk menemukan nama file yang mengandung kata:

temukan. -iname " word1 "

-Iname adalah versi "nama" yang tidak peka huruf besar-kecil.

Periode menentukan tempat untuk mulai mencari. Direktori saat ini sering merupakan pilihan yang baik.

Catatan: Anda mereferensikan " . " Di salah satu contoh Anda. Itu bagus untuk DOS, dan biasanya bagus di Microsoft Windows, tetapi merupakan kebiasaan yang sangat buruk untuk lingkungan Unix. Melihat itu membuat saya berpikir Anda terbiasa dengan Windows. Nah, pahami bahwa di Windows, "FIND" (atau "find") menempatkan teks dalam file. Unix berbeda: "grep" menempatkan teks dalam file, dan "menemukan" mencari nama file.

Sekarang, untuk mengecualikan kata 99, dan untuk menempatkannya dalam file teks, tambahkan teks berikut:

| grep -v word99 >> output.txt

Ini adalah kunci pipa, hampir selalu Shift-Backslash.

Jadi, sebagai contoh, jika Anda ingin melakukan keduanya, gunakan:

grep -iR "word1". | grep -v word99 >>
menemukan output.txt . -iname " word1 " | grep -v word99 >> output.txt

Bagian sebelum karakter pipa akan menjalankan perintah, dan mengirim output ke pipa gaya Unix. Kemudian, konten dikirim dari pipa ke input standar perintah berikutnya. grep -v akan melihat input standar yang diterimanya, dan mengecualikan apa yang Anda inginkan. grep -v akan mengirimkan hasil yang tersisa ke output standarnya. >> akan mengarahkan output standar perintah sebelumnya ke akhir file teks yang ditentukan.

Alasan mengapa Anda tidak melihat opsi yang terdokumentasi dalam perintah "find", tentang cara mengecualikan teks, adalah bahwa Unix sangat dirancang dengan gagasan membuat program yang lebih sederhana, dan menggunakan teknik perpipaan untuk menyebabkan efek yang rumit. Di lingkungan Microsoft, kode Microsoft lama lebih rumit dengan penanganan pipa, jadi program pada dasarnya mencoba untuk menggabungkan lebih banyak fungsi ke dalam setiap program. Di satu sisi, itu tampaknya lebih sederhana untuk pengguna akhir (memiliki semuanya bawaan), tetapi pendekatan itu kurang konsisten. Ketika Anda menggunakan Unix, jangan takut dengan perpipaan: begitu Anda terbiasa, Anda mungkin akan menyederhanakan banyak hal, tetapi karena Anda dapat menggunakan alat sederhana Anda dalam banyak situasi, sehingga Anda tidak perlu untuk mempelajari kembali teknik sederhana berulang-ulang (untuk setiap program yang berbeda).

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.