forループ入力ライン

forループ入力ライン

次のような多くの行を含むファイルがあります。

/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は、内部フィールド区切り文字()の文字で繰り返される「単語」を区切ります$IFSIFSコマンド実行中にnullに設定することで、この動作を一時的に無効にできますread。上記のパターンは常に1行ずつ繰り返されます。

<(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パーサーに慣れたいと思うでしょう。

関連情報