Dosyadaki desenlerle birlikte grep kullanarak benzersiz desenler yazdırın


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>

Beklenen çıktı:

"ExitWarning"
"SomeMessage"
"Help" 

İçinde patterns.txtbulunmayan terimleri nasıl yazdırabilirim Strings.xml? Ben eşleşti / eşsiz yazdırabilirsiniz çizgileri içinde Strings.xml, ama nasıl eşsiz yazdırırım desenleri ? Ggrep (GNU grep) sürüm 2.21 kullanıyorum, ancak diğer araçlara açıkım. Bu, bulamadığım başka bir sorunun kopyasıysa özür dileriz.

Yanıtlar:


25

Sen kullanabilirsiniz grep -osadece eşleştirme kısmını yazdırmak ve bir saniye kalıpları gibi bir sonuç kullanmak grep -vorijinal üzerine patterns.txtdosyanın:

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

Bu özel durumda join+ da kullanabilirsiniz sort:

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

bu oldukça zarif .. akıllı!
XXL

Birden fazla giriş dosyanız varsa (ör. Strings1.xmlVe Strings2.xml), -hilk grep'te de bayrağa ihtiyacınız olacaktır .
jayhendren

@jayhendren - evet ama hepsi grepbu seçeneği desteklemiyor. Birden fazla giriş dosyanız varsa, neden cathepsini basitçe göremediğinizi ve sonucu veremeyeceğinizi anlamıyorum grep.
don_crissti

5

En iyi yaklaşım muhtemelen @don_crissti'nin önerdiğidir, bu yüzden aynı temanın bir varyasyonu:

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

Bu temelde @ don_crissti yaklaşımının tersidir. Perl Uyumlu Düzenli İfadeler ( -P) ve -oanahtarın yalnızca eşleşen kısmını yazdırmak için grep kullanır . Sonra, normal ifade name=onu arar ve atar ( \K) ve sonra ilk "( .+?") 'e kadar bir veya daha fazla karakter arar . Bu, String.txtdosyada bulunan ve daha sonra proses ikamesi ( ) grep -vkullanılarak ters grep ( ) ' e girdi olarak aktarılan desenlerin listesi ile sonuçlanır .<(command)


2

cutMuhtemelen kullanırdım . Yani, göründüğü gibi, aradığınız alıntı dizeyi nerede bekleyeceğinizi biliyorsanız.

Eğer yaparsam:

{   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

... senin Örneğin benim kendi kopyasını kaydettikten sonra patterns.txtiçinde patve çıkışı yukarıdaki komutu çalıştırarak:

"ExitWarning"
"SomeMessage"
"Help"

cuther bir sınırlayıcı ile eşleşen girdi satırı için yalnızca ikinci "çift -dtırnaklı kaldırılan alanı stdout'a yazdırır -fve -sdiğerlerini yukarı doğru bastırır.

cutAslında ne yazdırır grep:

Introduction
BananaOpinion
MessageToUser

grepadında dosya işleneni , stdin desenindeki ixed dizeleriyle -veşleşmeyen satırlar arar .-F--f

"Eşleşecek olan ikinci olarak ayrılmış alana güvenebiliyorsanız , o zaman grep -Psadece -Fixed dizeleri ve sadece küçük kısımlarını eşleştirerek erl modu üzerinde bir optimizasyon olacaktır çünkü cutağır kaldırma yapar - ve hızlı yapar .


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

anlaşılması kolaydır, ancak patterns.txt dosyasındaki her satır için bir tane olmak üzere birden fazla grep işlemi oluşturma süresi vardır.


0

başka bir yol, patterns.txt ve Strings.xml dosyasını bir listeye koymak ve benzersiz satırları bulmaktır

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

açıklama:

cat patterns.txt Strings.xmlher şeyi tek bir listeye koyar. grep -oFf patterns.txther satırdaki çöpleri kaldırır. sortkendini açıklayıcı. tüm satırları sıralar. uniq -uyalnızca benzersiz çizgiler yazdırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.