だから私は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
。cat
none
開始として定義されます。これにより、<url>
前にaがない状況でエラーが発生するのを防ぎます<category>
。代替方法は、
gsub(/^ *| *$/,"",$2)
サンプル入力ファイルに表示されるカテゴリ名から先行/末尾のスペースを削除することです.xml
。
メモ:
上記のどれも完璧ではありません。正しい XML 入力ファイルの場合、実際の XML パーサーがより良いです。xmlstarlet。ただし、これには正しい形式のxmlファイルも必要です(<category>
たとえば、入力例に一致するタグはありません)。