xmlファイルをgrepし、結果に応じて出力をファイルにリダイレクトするスクリプト

xmlファイルをgrepし、結果に応じて出力をファイルにリダイレクトするスクリプト

だから私はXMLファイルを解析し、そのファイルの下にあるカテゴリ名に基づいて出力を新しいファイルにリダイレクトする簡単なスクリプトを書こうとしています。たとえば、XMLファイルは次のようになります。

<category> Music </Category>
<url>https://www.youtube.com/watch?v=waAlgFq9Xq8</url>
<category> Movies </Category>
<url>https://www.youtube.com/watch?v=g4U4BQW9OEk</url>

私のスクリプトは次のとおりです

for i in *.xml; do
    name=$(grep -i "<category>" $i | awk '{print $1}')
    line=$(grep -i -A1 "<category>" $i)
    echo "$line" >> $filename
done

たとえば、Movies.logには映画カテゴリ内のすべてのリンクが含まれ、Music.logには音楽カテゴリ内のすべてのリンクが含まれます。

ベストアンサー1

各カテゴリを繰り返すことを検討しましたか?このように:

for i in *.xml; do
    for category in $(sed -rn '/^<category>/{s/[^>]*> *([^ <]*).*/\1/p}' "$i"); do
        sed -rn "/^<category> *$category/,/^<category>/{s/<url> *([^ <]*).*/\1/p}" "$i" > "$category.log"
    done
done

アップデート:awkを使う

awk -v 'RS=<' -v 'cat=none' -F '>' \
'$1 ~ /^category$/ {gsub(/^ *| *$/,"",$2); cat=$2} \
$1 ~ /^url$/ {print $2 >> cat".log"}' \
*.xml
  • これにより、入力ファイルが繰り返されるのを防ぎ、.logすべてのカテゴリのファイルに追加されます。

  • awkのレコード区切り記号割り当てを使用することは、-v 'RS=<'カテゴリ/ URLタグをどこでも(行の先頭だけでなく)見つけることができることを意味します。改行文字は xml データのどこにでも表示できます。

  • これをフィールド区切り文字の設定と組み合わせる'>'と、各レコードの最初のフィールドはxmlタグ名と同じになります。

  • awk は、最初のフィールドが「category」のレコードに会うたびに、cat変数をそのカテゴリの名前に設定します。

  • awkは、最初のフィールドが「url」のレコードを検出すると、そのURLをファイルに追加しますcat.log

  • catnone開始として定義されます。これにより、<url>前にaがない状況でエラーが発生するのを防ぎます<category>

  • 代替方法は、gsub(/^ *| *$/,"",$2)サンプル入力ファイルに表示されるカテゴリ名から先行/末尾のスペースを削除することです.xml


メモ:

上記のどれも完璧ではありません。正しい XML 入力ファイルの場合、実際の XML パーサーがより良いです。xmlstarlet。ただし、これには正しい形式のxmlファイルも必要です(<category>たとえば、入力例に一致するタグはありません)。

おすすめ記事