"Buka" - pola mana yang tidak cocok


13

Saya mencari perintah atau skrip untuk melakukan hal berikut - diberikan:

file1.txt:

abcd
efgh 
ijkl
mnop

file2.txt:

123abcd123
123efgh123
123mnop123

Saya ingin perintah yang melakukan sesuatu seperti ini:

ungrep file1.txt file2.txt

dan mengembalikan yang berikut:

ijkl

Dengan kata lain itu memberi saya baris di file1.txt yang tidak akan mengembalikan hasil apa pun pada grep file2.txt. Saya tahu bahwa saya bisa melakukan ini dengan mengulangi melalui file1.txt, grepping file2.txt untuk setiap baris dan menyimpan hasilnya, dan mengeluarkan setiap baris yang hasilnya kosong, tetapi saya berharap cara yang lebih efisien untuk melakukan ini.

Jawaban:


18

Dengan GNU grephal-hal berikut ini akan berfungsi. Menggunakan -fopsi, berikan file1.txtsebagai "file pola" - tetapi juga berikan sebagai file data untuk kedua kalinya. Gunakan -ountuk melaporkan hanya bagian yang cocok. Akhirnya ekstrak kata-kata yang hanya cocok sekali - ini sesuai dengan baris dari file1.txtyang tidak menemukan kecocokan file2.txt.

grep -h -o -f  file1.txt file2.txt file1.txt | sort | uniq -u
ijkl

Deskripsi yang sangat bagus. Terima kasih dan +1.
unxnut

4
Anda dapat mencapai efek yang sama tanpa ketegaran grep:, sort file1.txt <(grep -of file1.txt file2.txt) | uniq -utetapi, seperti solusi Anda, ini hanya berfungsi ketika file pola tidak benar-benar mengandung metachar karakter regex.
rici

@rici, itu adalah poin yang sangat bagus
iruvar

2
Peningkatan:grep -oFf file1.txt file2.txt | sort file1.txt - | uniq -u
Stéphane Chazelas

10

Anda bisa melakukannya dengan awkseperti:

awk '
  NR == FNR {w[$0]; next}
  {for (i in w) if (index($0,i)) delete w[i]}
  END {for (i in w) print i}' file1.txt file2.txt

Dengan menggunakan index, kami mencari substring daripada mencocokkan ekspresi reguler.

Karena kami menghapus kata dari array segera setelah kami menemukan kecocokan, kami menghindari pencarian yang tidak perlu.


1
Saya hanya akan menerima yang ini. Itu tidak meminta penyortiran O (n log n) apa pun, dan tidak gagal secara aneh ketika polanya berisi meta-karakter regex, dan dapat diperluas untuk mendukung regex.
Kaz

Saya tidak percaya bahwa hanya mengevaluasi w[$0]memiliki efek samping menambahkan kunci ke array.
Kaz

1
@ Ka, ya itu bisa membingungkan, dan Anda menemukan banyak skrip yang tidak sengaja mengalokasikan elemen array secara tidak sengaja dengan melakukan if (a[$1])alih - alih if ($1 in a)misalnya. Ini adalah kasus setiap awktermasuk yang asli awkdan nawk, tetapi melihat standar kemarin, saya tidak dapat menemukannya ditentukan.
Stéphane Chazelas

1
@Kaz Berikut ini kutipan POSIX: "Aplikasi harus memastikan bahwa indeks multi-dimensi yang digunakan dengan operator di dalam tanda kurung. Operator dalam , yang menguji keberadaan elemen array tertentu, tidak akan menyebabkan elemen itu ada. Setiap referensi lain ke elemen array yang tidak ada akan secara otomatis membuatnya. " Itu dapat ditemukan dengan menggulir satu atau dua paragraf dari sini .
jw013

1
Selama file1tidak besar (untuk beberapa nilai besar), saya lebih suka solusi ini karena tidak memerlukan penyortiran file2dan diharapkan akan jauh lebih efisien.
jw013
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.