셸을 사용하여 특정 패턴 반복

셸을 사용하여 특정 패턴 반복

처리하고 일부 항목을 가져와야 하는 파일이 있습니다. 파일 형식은 다음과 같습니다.

입력 예:

String1:"Hello"
String2:"World"
String3:"Question"
End
String1:"HelloAgain"
String5:"Answer"
End
String1:"NewEntry"
String2:"Foo"
String5:"NewFile"
End

스크립트는 반복하여 String1을 찾아서 인쇄하려고 시도합니다. String2도 블록에 있으면 String1에 추가되어 인쇄됩니다.

예제 출력:

Hello World
HelloAgain
NewEntry Foo

이러한 각 블록을 반복해야 합니다. 여기서 차단은 각 "End" 문자열 사이의 내용을 의미합니다. 다음과 같은 스크립트가 있습니다.

    cat $1 | while read line
do
    if [[ $line == "String1="* ]];
    then
        string1=$line
    fi
    if [[ $line == "String2="* ]];
    then
        string2=$line
    fi
    if [[ $line == "End" ]];
    then
        if [ $string1 ];
            then
            echo "string1/"$string1"
        fi
        if [ $string1 ] && [ $string2 ];
            then
            echo $string1" "$string2
        fi
    #Reset values
    string1=''
    string2=''
    fi
done

코드는 잘 작동하지만 이러한 블록 간의 처리가 더 복잡해질 수 있습니다. 이러한 블록을 반복하고 이러한 블록 항목을 처리하는 가장 좋은 방법은 무엇입니까?

참고: 이 파일은 속성 파일입니다.

답변1

귀하가 제공한 입력과 요청된 출력을 고려하면 다음과 같습니다.

$ awk -F: '$0 == "End" { printf "\n" } $1 ~ /^String[12]$/ { gsub( /\"/, "", $2 ); printf( "%s ", $2)}' input
Hello World
HelloAgain
NewEntry Foo

답변2

perl -F':|"' -lane 'if ($out && $_ eq "End") {print "$out"; $out=""};
  $out  = $F[2] if ($F[0] eq "String1");
  $out .= $F[2] if ($out && $F[0] eq "String2")' input.txt

이 Perl 스크립트는 출력에서 ​​큰따옴표를 제거할 필요가 없도록 필드 구분 기호로 :또는 를 사용합니다. "이는 우리가 추출해야 함을 의미합니다.제삼field 대신 두 번째 필드를 사용합니다. 이제 첫 번째 필드 :".Perl 배열은 0부터 시작하므로 $F[2].

인쇄할 내용이 있으면 레코드("청크")의 출력(String1 자체)만 인쇄합니다.또는String1과 String2가 존재합니다. 즉, 일치하지 않는 레코드에 대해 빈 줄을 인쇄하지 않습니다.

이것은 동일한 알고리즘입니다 awk.

awk -F':|"' 'out && $0 == "End"  { print out; out="" };
  $1 == "String1" { out=$3 };
  out && $1 == "String2" { out = out$3 }' input.txt

관련 정보