次のようにxmlファイル形式を見つけることができます。
find /tmp/ -type f -name '*.xml'
しかし、次のようなXMLのみを見つけるように構文をどのように変更できますか?
<Name>some words</Name>
次の間に内容を印刷します。
<Name> ------ </Name>
期待される出力
some words
例 – xml ファイルには次のものが含まれます。
<Name>files_with_extra_data</Name>
期待される出力
files_with_extra_data
答え1
簡単な解決策はsedを使用することです。
find /tmp -name '*.xml' -exec sed -n 's/<Name>\([^<]*\)<\/Name>/\1/p' {} +
正規表現はタグを一致させ、タグ間の内容を印刷します。エスケープ文字を削除すると、読みやすくなります。
s / <Name>([^<]*)</Name> / \1
角かっこは "<"以外のすべての文字と一致し、\ 1にマップされます。
コメントで述べたように、これは簡単な解決策になります。正規表現は、構造化テキストのすべての可能な変形に対処することはできません。したがって、タグまたは他のタグの間に複数行がある場合は機能せず、実際のXMLパーサーを使用する必要があります。
答え2
このような単純なXML操作の場合は、次を使用します。XML2そしてcut
。 (またはsed
、またはawk
、またはperl
)。
find . -iname '*.xml' -exec bash -c 'xml2 < {}' \; | grep '/Name=' |
cut -d '=' -f2-
または
find . -iname '*.xml' -exec bash -c 'xml2 < {}' \; | sed -n -e 's/^[^=]*\/Name=//p'
または
find . -iname '*.xml' -exec bash -c 'xml2 < {}' \; |
awk -F'=' '/Name=/ {$1=""; sub(/^ /,"",$0); print }'
(sub()
awkバージョンの関数呼び出しは、$ 1を ""に設定した後に残った先行スペースを削除します。awkは入力行からフィールドを削除できませんsplit()
。 . 不要なフィールドを削除し、配列を印刷用の文字列に連結しますawk
。join()
perl
または
find . -iname '*.xml' -exec bash -c 'xml2 < {}' \; |
perl -F= -lane 'if (m:/Name=:) { delete @F[0]; print @F}'
xml2
XML形式のデータを、行ベースのテキストユーティリティ(たとえば、、、、awk
などsed
)を使用して処理するのに適した行ベースのperl
形式に変換します。2xml
ラインベースの形式を正しい形式のXMLに変換するプログラムが付属しています。
より複雑なタスクに使用します。xmlstarlet
xmlstarlet
XMLファイルのデータを一覧表示、照会、抽出、および変更するために使用できるXML処理ツール。
どちらもDebianや他のLinuxディストリビューション用にパッケージ化できます。
私の考えのための最善の解決策は、類似またはperl
XMLpython
解析ライブラリを持つ言語を使用することです。 xmlstarlet
シェルでXMLファイルを処理するのに適していますが、非常に複雑な検索のためのコマンドラインを書くことは、スクリプトを書いたりperl
作業を実行したりするよりもpython
多くの作業になります(読み取りとデバッグが難しくなります)。部分的には、私はこれらの言語でより多くのプログラミングをしており、使いやすくなることがわかったからです...だからです。非常に特定の日にのみ使用できるドメイン固有の言語/ツールではない操作。
答え3
そしてpcregrep
:
pcregrep -rMh --include='\.xml\z' -o1 '(?s)<name>(.*?)</name>' .
答え4
sed -n '/Name/{s/.*<Name>//;s/<\/Name.*//;p;}' "$FULL_XML_PATH"