Cetak pola yang tidak cocok, gunakan grep dengan pola dari file


15

patterns.txt:

"BananaOpinion"
"ExitWarning"
"SomeMessage"
"Help"
"Introduction"
"MessageToUser"

Strings.xml

<string name="Introduction">One day there was an apple that went to the market.</string>
<string name="BananaOpinion">Bananas are great!</string>
<string name="MessageToUser">We would like to give you apples, bananas and tomatoes.</string>

Output yang diharapkan:

"ExitWarning"
"SomeMessage"
"Help" 

Bagaimana cara mencetak istilah patterns.txtyang tidak ditemukan Strings.xml? Saya dapat mencetak cocok / yang tak tertandingi garis di Strings.xml, tapi bagaimana saya mencetak tak tertandingi pola ? Saya menggunakan ggrep (GNU grep) versi 2.21, tetapi saya terbuka untuk alat lain. Mohon maaf jika ini adalah duplikat dari pertanyaan lain yang tidak dapat saya temukan.

Jawaban:


25

Anda dapat menggunakan grep -ountuk mencetak hanya bagian yang cocok dan menggunakan hasilnya sebagai pola untuk sedetik grep -vpada patterns.txtfile asli :

grep -oFf patterns.txt Strings.xml | grep -vFf - patterns.txt

Meskipun dalam kasus khusus ini Anda juga dapat menggunakan join+ sort:

join -t\" -v1 -j2 -o 1.1 1.2 1.3 <(sort -t\" -k2 patterns.txt) <(sort -t\" -k2 strings.xml)

ini cukup elegan .. pintar!
XXL

Jika Anda memiliki banyak file input (mis. Strings1.xmlDan Strings2.xml), Anda juga akan memerlukan -htanda pada grep pertama.
jayhendren

@ jayhendren - yeah tapi tidak semua grepmendukung opsi itu. Jika Anda memiliki banyak file input, saya tidak mengerti mengapa Anda tidak bisa dengan mudahnya catdan mengirimkan hasilnya grep.
don_crissti

5

Pendekatan terbaik mungkin yang disarankan @don_crissti, jadi inilah variasi pada tema yang sama:

$ grep -vf <(grep -Po 'name=\K.+?"' Strings.xml) patterns.txt
"ExitWarning"
"SomeMessage"
"Help"

Ini pada dasarnya adalah kebalikan dari pendekatan @ don_crissti. Ini menggunakan grep dengan Ekspresi Reguler Biasa Kompatibel ( -P) dan -osaklar untuk mencetak hanya bagian yang sesuai dari baris tersebut. Kemudian, regex mencari name=dan membuangnya ( \K), lalu mencari satu atau lebih karakter hingga yang pertama "( .+?"). Ini menghasilkan daftar pola yang ada dalam String.txtfile yang kemudian diteruskan sebagai input ke grep terbalik ( grep -v) menggunakan substitusi proses ( <(command)).


2

Saya akan menggunakan cut, mungkin. Artinya, jika, seperti yang terlihat, Anda tahu di mana harus mengharapkan string yang dikutip yang Anda cari.

Jika aku melakukan:

{   cut  -sd\" -f2 |
    grep -vFf- pat
}   <<\IN
#   <string name="Introduction">One day there was an apple that went to the market.</string>
#   <string name="BananaOpinion">Bananas are great!</string>
#   <string name="MessageToUser">We would like to give you apples, bananas and tomatoes.</string>
IN

... setelah menyimpan salinan saya sendiri dari contoh Anda patterns.txtdi patdan menjalankan perintah di atas output adalah:

"ExitWarning"
"SomeMessage"
"Help"

cutmencetak ke stdout hanya "tanda kutip ganda -ddihilangkan -funtuk setiap jalur input yang cocok dengan pembatas dan -smenekan semua yang lain.

Apa yang cutsebenarnya dicetak grepadalah:

Introduction
BananaOpinion
MessageToUser

grepmencari operan file bernama untuk baris yang -vtidak cocok dengan -Fstring ixed di ile -pola stdin -f.

Jika Anda dapat mengandalkan "bidang yang telah direvisi kedua sebagai bidang yang cocok, maka itu pasti akan menjadi optimasi atas grep -Pmode erl dengan hanya mencocokkan -Fstring ixed dan hanya sebagian kecil darinya karena cutmelakukan pengangkatan yang berat - dan melakukannya dengan cepat .


1
for p in $(cat patterns.txt); do if ! grep $p strings.xml &>/dev/null; then echo $p; fi; done

mudah dimengerti tetapi memiliki downtime memunculkan banyak proses grep, satu untuk setiap baris di patterns.txt.


0

Cara lain adalah dengan menempatkan patterns.txt dan Strings.xml ke dalam satu daftar dan menemukan baris unik

cat patterns.txt Strings.xml | grep -oFf patterns.txt | sort | uniq -u

penjelasan:

cat patterns.txt Strings.xmlmenempatkan semuanya dalam satu daftar. grep -oFf patterns.txtmenghilangkan sampah di setiap baris. sortcukup jelas. urutkan semua baris. uniq -uhanya mencetak garis-garis unik.

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.