ファイルからのパターンでgrepを使用して、一致しないパターンを印刷する


14

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>

期待される出力:

"ExitWarning"
"SomeMessage"
"Help" 

patterns.txtない用語を印刷するにはどうすればよいStrings.xmlですか?私はマッチ/比類のない印刷できるではStrings.xml、しかし、どのように私は、比類のない印刷かのパターンを?ggrep(GNU grep)バージョン2.21を使用していますが、他のツールも利用できます。これが私が見つけることができなかった別の質問の複製である場合、おologiesび申し上げます。

回答:


24

あなたは使用できるgrep -oだけ一致する部分を印刷し、第二のためのパターンとして結果を使用するためにgrep -v、元のpatterns.txtファイル:

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

この特定のケースでは、join+ も使用できますがsort

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

これは非常にエレガントです..スマート!
XXL

複数の入力ファイル(Strings1.xmlおよびなどStrings2.xml)がある場合-h、最初のgrepにもフラグが必要です。
jayhendren

@jayhendren-ええ、しかしすべてがgrepそのオプションをサポートしているわけではありません。複数の入力ファイルがある場合、単純catにすべてを入力して結果をにパイプできない理由はわかりませんgrep
-don_crissti

5

おそらく最良のアプローチは@don_crisstiが提案したものであるため、同じテーマのバリエーションを次に示します。

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

これは基本的に@don_crisstiのアプローチの逆です。Perl互換正規表現(-P)と-oスイッチでgrepを使用して、行の一致部分のみを印刷します。次に、正規表現name=はそれを探して破棄し(\K)、最初の文字".+?")まで1つ以上の文字を探します。これにより、String.txtファイル内に存在するパターンのリストが生成され、プロセス置換()grep -vを使用して入力としてリバースgrep()に渡されます。<(command)


2

cutおそらくを使用します。つまり、表示されているように、探している引用符で囲まれた文字列がどこにあるかを知っている場合です。

私が行った場合:

{   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

...あなたの例の私自身のコピーを保存した後patterns.txtpatし、上記のコマンドを実行している出力は、次のとおりです。

"ExitWarning"
"SomeMessage"
"Help"

cut区切り文字に一致する入力行ごとに、2番目の"二重引用符で区切られた-dield のみを標準出力に出力し、他のすべて-f-s抑制します。

何がcut実際に印刷さgrepれます。

Introduction
BananaOpinion
MessageToUser

grep指定されたファイルオペランドを検索して、stdinパターンファイル内-v-F固定文字列と一致しない行を探します。--f

"一致するフィールドとして2番目に区切られたフィールドに依存できる場合、それは間違いなく、固定された文字列とそれらのごく一部grep -Pだけを一致さ-Fせることによるerlモードの最適化にcutなります


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

理解するのは簡単ですが、patterns.txtの各行に1つずつ、複数のgrepプロセスを生成するダウンタイムがあります。


0

別の方法は、patterns.txtとStrings.xmlを1つのリストに入れて、一意の行を見つけることです。

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

説明:

cat patterns.txt Strings.xmlすべてを1つのリストに入れます。 grep -oFf patterns.txt各行のゴミを削除します。 sort自明です。すべての行をソートします。 uniq -u一意の行のみを印刷します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.