私は基本的に正規表現でgrepしています。出力では、regexpに一致する文字列のみを表示したいと思います。
一連のXMLファイル(ほとんどの場合、1行に大量のデータが含まれる1行のファイル)で、MAIL _で始まるすべての単語を取得したいと思います。
また、シェルのgrepコマンドで、一致した単語のみを指定し、行全体(この場合はファイル全体)を指定しないようにします。
どうすればよいですか?
私が試してみました
grep -Gril MAIL_* .
grep -Grio MAIL_* .
grep -Gro MAIL_* .
まず、UbuntuでインストールされるGNU grepでは、-Gフラグ(基本的な正規表現を使用)がデフォルトであるため、省略できますが、さらに良いことに、-で拡張正規表現を使用します。 E。
-rフラグは、ディレクトリのファイル内の再帰検索を意味します。これが必要です。
また、-oフラグを使用して、行の一致する部分を印刷することもできます。また、ファイル名を省略するには、-hフラグが必要です。
あなたが犯した唯一の間違いは正規表現そのものです。 *の前に文字指定を見逃しました。コマンドは次のようになります。
grep -Ehro 'MAIL_[^[:space:]]*' .
サンプル出力(再帰的ではありません):
$ echo "Some garbage MAIL_OPTION comes MAIL_VALUE here" | grep -Eho 'MAIL_[^[:space:]]*'
MAIL_OPTION
MAIL_VALUE
次のコマンドを試してください
grep -Eo 'MAIL_[[:alnum:]_]*'
grep -o or --only-matching
完全な行ではなく、一致するテキストのみを出力しますが、問題は、制限的または貪欲ではなく、実際にファイル全体に一致する正規表現である可能性があります。
コメントからThorの回答まで、_MAIL_.*
_テキストがテキストノードであるか属性であるかを区別する必要があるようです。XMLドキュメントに表示されるたびにテキストを分離するだけではありません。 GrepはXMLを解析できません そのための適切なXMLパーサーが必要です 。
コマンドラインxmlパーサーは xmlstarlet です。 Ubuntuにパッケージ化されています。
このサンプルファイルサンプルファイルでの使用:
_$ cat test.xml
<some_root>
<test a="MAIL_as_attribute">will be printed if you want matching attributes</test>
<bar>MAIL_as_text will be printed if you want matching text nodes</bar>
<MAIL_will_not_be_printed>abc</MAIL_will_not_be_printed>
</some_root>
_
テキストノードを選択するには、次のものを使用できます。
_$ xmlstarlet sel -t -m '//*' -v 'text()' -n test.xml | grep -Eo 'MAIL_[^[:space:]]*'
MAIL_as_text
_
そして属性を選択するために:
_$ xmlstarlet sel -t -m '//*[@*]' -v '@*' -n test.xml | grep -Eo 'MAIL_[^[:space:]]*'
MAIL_as_attribute
_
簡単な説明:
//*
_はドキュメント内のすべての要素を選択するXPath式であり、text()
は子のテキストノードの値を出力するため、テキストノードを除くすべてが除外されます//*[@*]
_は、ドキュメント内のすべての属性を選択し、_@*
_がそれらの値を出力するXPath式です。