このような行がたくさんあるファイルがあります
/item/pubDate=日曜日、2014年2月23日 00:55:04 +010
これを実行すると
echo "/item/pubDate=Sun, 23 Feb 2014 00:55:04 +010" | grep -Po "(?<=\=).*"
Sun, 23 Feb 2014 00:55:04 +010
正しい日付を取得しました (すべて 1 行で)。今度は、xml ファイル内の多数の日付でこれを試してみたいと思います。これを使用しても問題ありません。
xml2 < date_list | egrep "pubDate" | grep -Po "(?<=\=).*"
Fri, 22 Jan 2016 17:56:29 +0100
Sun, 13 Dec 2015 18:33:02 +0100
Wed, 18 Nov 2015 15:27:43 +0100
...
しかし、今私はbashプログラムで日付を使いたいのですが、この出力が得られます
for fecha in $(xml2 < podcast | egrep "pubDate" | grep -Po "(?<=\=).*"); do echo $fecha; done
Fri,
22
Jan
2016
17:56:29
+0100
Sun,
13
Dec
2015
18:33:02
+0100
Wed,
18
Nov
2015
15:27:43
+0100
最初の例と 2 番目の例のように、日付を 1 行 (変数 fecha) で出力したいのですが、方法がわかりません。
答え1
代わりに次のようにしてください:
while IFS= read -r fecha; do
echo $fecha
done < <(xml2 < podcast | egrep "pubDate" | grep -Po "(?<=\=).*")
Bash は、ループする「単語」を内部フィールド区切り文字 ( $IFS
) の文字で区切ります。コマンドIFS
の実行中は何も設定しないことで、この動作を一時的に無効にすることができますread
。上記のパターンは、常に行ごとにループします。
<(command)
コマンドの出力を実際のファイルのように見せ、それをread
ループにリダイレクトします。
$ while IFS= read -r line; do echo $line; done < <(cat ./test.input)
Fri, 22 Jan 2016 17:56:29 +0100
Sun, 13 Dec 2015 18:33:02 +0100
Wed, 18 Nov 2015 15:27:43 +0100
答え2
xml2 < date_list | egrep "pubDate" | grep -Po "(?<=\=).*" \
| while read L
do
echo $L
done
読む行ごとに分割し、要求されない限り単語を分割しません。 :-)
しかし、正規表現を使用して XML に取り組むことは、銃撃戦にナイフを持っていくようなものです。上記のパイプラインが見逃したり、誤ってキャプチャしたりする有効な XML を構築することは非常に簡単です。
XML を多く扱う場合は、SAX パーサーに慣れておく必要があります。