입력 라인에 대한 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

나는 정확한 날짜를 얻습니다 (모두 한 줄에). 이제 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

첫 번째와 두 번째 예제와 같이 한 줄(변수 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 파서에 익숙해지고 싶을 것입니다.

관련 정보