すべてのxmlファイルで特定のタグのディレクトリを繰り返し検索し、タグ値をgrepします。

すべてのxmlファイルで特定のタグのディレクトリを繰り返し検索し、タグ値をgrepします。

Ubuntu 14.04信頼できるTal。

何百ものxmlファイルを含むことができ、そして順番に多くのxmlファイルを含むことができる "testmag"というディレクトリがあるとしましょう。 xmlファイルの名前はわかりませんが、そのうちの1つにタグが含まれていることはわかっています<dbname>....</dbname>

上記のタグを含むファイルを見つけて、タグ値を端末に出力として提供するにはどうすればよいですか?

答え1

find以下は、一致する項目を含むファイルのファイル名も出力するソリューションです。

find . -name "*.xml" -exec grep '<dbname>' {} \;             \
                     -exec echo -e {}"\n" \;                 \
                     | sed 's/<dbname>\(.*\)<\/dbname>/\1/g'

説明する

  1. find . -name "*.xml"現在のディレクトリですべてのxmlファイルを再帰的に見つけます。
  2. -exec grep '<dbname>' {} \;各ファイルの検索パターン<dbname>
  3. -exec echo -e {}"\n" \;echoファイル名+新しい行(-eオプションはecho解釈を作成します\n
  4. | sed 's/<dbname>\(.*\)<\/dbname>/\1/g'sedラベルの間に含まれるフィールドのみを印刷するパイプ出力<dbname></dbname>

echo -e ...注1:必要に応じて新しい行を追加したり、行に下線を付けたりするなど、各ファイルの結果が明確にリストされるように出力形式を指定できます。

.注2:各ファイルのパスは(たとえば)./subfolder1/file.xml。絶対パスが必要な場合はを選択してくださいfind $PWD -name ...

答え2

適切なXMLパーサーを使用してXMLを解析します。

shopt -s globstar nullglob
for file in **/*.xml; do 
    dbname=$(xmlstarlet sel -t -v '//dbname' "$file")
    [[ -n "$dbname" ]] && printf "%s\t%s\n" "$file" "$dbname"
done

答え3

find次のように使用しますxq

find testmag -type f -name '*.xml' -exec xq -r '..|(.dbname? // empty)' {} +

*.xmlこれは、一致する名前のディレクトリ内または下のすべての一般的なファイルを探しますtestmag。この配置では、その文書で見つかったxq各ノードの値を抽出するための呼び出しが行われます。dbname

xqjqで配布されるXMLに似たパーサーです。yqhttps://kislyuk.github.io/yq/


このノードを含むすべてのXMLファイルのファイル名が必要ですか?

find testmag -type f -name '*.xml' -exec xq -e '..|(.dbname? // empty)' {} \; -print

これは、ノードの値を抽出するよりも少し遅いですが、各ファイルxqに対して一度呼び出す必要があるためです。

答え4

XMLS次のファイルを含むディレクトリがあるとします。

cat XMLS/file1
foo bar <dbname>target</dbname> baz
foo foo

cat XMLS/file2
<name>notarget</name>

私は次のコマンドを使います:

grep -r '<dbname>' XMLS/ | sed 's/.*<dbname>\(.*\)<\/dbname>.*/\1/'
target

ご覧のとおり、タグ内の値を返します<dbname>。タグ内の値で<name>はありません


再帰検索-rフラグ。grep

sed文字列から値を除くすべてを削除しますtarget

関連情報