처리하고 일부 항목을 가져와야 하는 파일이 있습니다. 파일 형식은 다음과 같습니다.
입력 예:
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