GNU/Linux >> Belajar Linux >  >> Linux

Cari File Teks Di Mana Dua Kata Berbeda Ada (Urutan apa saja, Baris Apa Saja)?

Saya mencari cara untuk mencari file di mana dua contoh kata ada di file yang sama. Saya telah menggunakan yang berikut ini untuk melakukan pencarian saya hingga saat ini:

find . -exec grep -l "FIND ME" {} ;

Masalah yang saya hadapi adalah jika tidak ada tepat satu spasi antara "FIND" dan "ME", hasil pencarian tidak menghasilkan file. Bagaimana cara mengadaptasi string pencarian sebelumnya di mana kedua kata “FIND” dan “ME ada di file sebagai lawan dari “FIND ME”?

Saya menggunakan AIX.

Jawaban yang Diterima:

Dengan alat GNU:

find . -type f  -exec grep -lZ FIND {} + | xargs -r0 grep -l ME

Anda dapat melakukan secara standar:

find . -type f -exec grep -q FIND {} ; -exec grep -l ME {} ;

Tapi itu akan berjalan hingga dua grep s per file. Untuk menghindari menjalankan banyak grep s dan masih portabel sambil tetap mengizinkan karakter apa pun dalam nama file, Anda dapat melakukan:

convert_to_xargs() {
  sed "s/[[:blank:]"']/\\&/g" | awk '
    {
      if (NR > 1) {
        printf "%s", line
        if (!index($0, "//")) printf "\"
        print ""
      }
      line = $0
    }'
    END { print line }'
}

export LC_ALL=C
find .//. -type f |
  convert_to_xargs |
  xargs grep -l FIND |
  convert_to_xargs |
  xargs grep -l ME

Idenya adalah untuk mengonversi output find ke dalam format yang cocok untuk xargs (yang mengharapkan kosong (SPC/TAB/NL di C locale, YMMV in other locales) daftar kata yang dipisahkan di mana tanda kutip tunggal, ganda, dan garis miring terbalik dapat menghindari titik kosong dan satu sama lain).

Umumnya Anda tidak dapat mem-post-proses output find -print , karena memisahkan nama file dengan karakter baris baru dan tidak menghindari karakter baris baru yang ditemukan dalam nama file. Misalnya jika kita melihat:

./a
./b

Kami tidak tahu apakah itu satu file bernama b dalam direktori bernama a<NL>. atau jika itu adalah dua file a dan b di direktori saat ini.

Dengan menggunakan .//. , karena // tidak dapat muncul sebaliknya di jalur file sebagai output oleh find (karena tidak ada direktori dengan nama kosong dan / tidak diperbolehkan dalam nama file), kita tahu bahwa jika kita melihat baris yang berisi // , maka itulah baris pertama dari nama file baru. Jadi kita bisa menggunakan awk itu perintah untuk keluar dari semua karakter baris baru kecuali yang mendahului baris tersebut.

Jika kita ambil contoh di atas, find akan menampilkan dalam kasus pertama (satu file):

.//a
./b

Awk mana yang lolos ke:

.//a
./b

Sehingga xargs melihatnya sebagai satu argumen. Dan dalam kasus kedua (dua file):

.//a
.//b

Yang awk akan pergi apa adanya, jadi xargs melihat dua argumen.

Terkait:Mode mouse Tmux aktif tidak memungkinkan untuk memilih teks dengan mouse?

Anda memerlukan LC_ALL=C jadi sed , awk (dan beberapa implementasi xargs ) berfungsi untuk urutan byte yang berubah-ubah (meskipun itu tidak membentuk karakter yang valid di lokal pengguna), untuk menyederhanakan kosong definisi hanya untuk SPC dan TAB dan untuk menghindari masalah dengan interpretasi yang berbeda dari karakter yang pengkodeannya berisi pengkodean garis miring terbalik oleh utilitas yang berbeda.


Linux
  1. Bandingkan Dua Kolom File Yang Berbeda Dan Cetak Jika Cocok?

  2. Linux – Di mana Metadata Untuk File Pdf? Bisakah Saya Memasukkan Metadata Ke File Pdf Apa Pun?

  3. Bagaimana Anda mencari file yang berisi akhiran baris DOS (CRLF) dengan grep di Linux?

  1. Linux:hapus ekstensi file untuk banyak file

  2. bagaimana saya bisa mencari file dan meng-zip-nya dalam satu file zip

  3. Cara mencari file di file war,ear dan jar secara rekursif di Linux

  1. Cara Menambahkan Nomor Baris Ke File Teks Di Linux

  2. Ekstrak Nilai Antara Dua Pola Pencarian Pada Baris Yang Sama?

  3. Bagaimana Cara Mencari File Berdasarkan Ukuran Dan Ekstensi?