다음 텍스트가 있습니다.
Name= Garen
Class= 9C
School= US
Name= Lulu
Class= 4A
Name= Kata
Class= 10D
School= UK
다음 awk cmd를 얻었습니다.
awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt
하지만 새로운 줄로 출력됩니다. 이와 같이:
Name= Garen Class= 9C School= US
Name= Lulu Class= 4A Name= Kata Class= 10D School= UK
다음과 같이 출력하고 싶습니다.
Name= Garen ,Class= 9C ,School= US
Name= Lulu , Class= 4A ,
Name= Kata ,Class= 10D ,School= UK
다음과 같은 상황이 발생하는 경우:
Name= Garen
Class= 9C
Last Name= Wilson
School= US
Name= Lulu
Class= 4A
Last Name= Miller
Name= Kata
Class= 10D
School= UK
Last Name= Thomas
그리고 인쇄하세요:
Name= Garen,Class= 9C,School= US
Name= Lulu,Class= 4A
Name= Kata,Class= 10D,School= UK
답변1
$ awk -v OFS=',' '/^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
Name= Garen,Class= 9C,School= US
Name= Lulu,Class= 4A
Name= Kata,Class= 10D,School= UK
질문에 업데이트된 입력을 사용하면 다음과 같은 결과가 나옵니다.
Name= Garen,Class= 9C,Last Name= Wilson ,School= US,
Name= Lulu,Class= 4A,Last Name= Miller,
Name= Kata,Class= 10D,School= UK,Last Name= Thomas
이 비트를 제거하려면 Last Name
코드에서 명시적으로 무시하세요 awk
.
$ awk -v OFS=',' '/^Last Name/ { next } /^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
Name= Garen,Class= 9C,School= US,
Name= Lulu,Class= 4A,
Name= Kata,Class= 10D,School= UK
이 코드는 주석이 포함된 독립 실행형 프로그램 awk
으로 제공됩니다 .awk
BEGIN {
# Set output field separator to a comma.
# This can also be done with -v OFS="," on the command line.
OFS = ","
}
/^Last Name/ {
# Ignore these lines
next
}
/^Name/ {
# A line starts with "Name".
# Print the accumulated line and reset the line variable.
# Continue immediately with next line of input.
if (line != "")
print line
line = $0
next
}
{
# Accumulate lines in the line variable.
# Delimit each input data with OFS (a comma).
line = line OFS $0
}
END {
# Print the last accumulated line.
if (line != "")
print line
}
( sed
이것은 거의 동일한 솔루션입니다.다른 질문의 답변)
/^Last Name/ d; # ignore these lines
/^Name/ b print_previous; # print previous record
H; # append this line to hold space
$ b print_previous; # print previous (last) record
d; # end processing this line
:print_previous; # prints a record accumulated in the hold space
x; # swap in the hold space
/^$/ d; # if line is empty, delete it
s/\n/,/g; # replace embedded newlines by commas
# (implicit print)
실행하세요:
$ sed -f script.sed file
Name= Garen,Class= 9C,School= US
Name= Lulu,Class= 4A
Name= Kata,Class= 10D,School= UK
답변2
awk
아래와 같이 한 줄의 코드를 사용하여 이를 달성 할 수 있습니다 .
awk -F\< '/Name=/ {LGT=length($2);printf("\n%s,",substr($2,6,LGT))};
/Class=/ {LGT=length($2);printf(" %s,",substr($2,6,LGT))};
/School=/ {LGT=length($2);printf(" %s",substr($2,6,LGT))};
END {printf("\n") }' file.txt
이 솔루션은 file.txt
에 나타나는 순서대로 레코드(즉, 원본 파일의 줄)를 인쇄 합니다 file.txt
. .awk
이전 답변에서 볼 수 있듯이 file.txt에는 다음이 포함됩니다.
<text>Name= Garen</text>
<text>Class= 9C</text>
<text>School= US</text>
<text>Name= Lulu</text>
<text>Class= 4A</text>
<text>Name= Kata</text>
<text>Class= 10D</text>
<text>School= UK</text>
출력은 다음과 같습니다
Name= Garen, Class= 9C, School= US
Name= Lulu, Class= 4A
Name= Kata, Class= 10D, School= UK
답변3
awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt
All $Name
, $Class
및 는 $School
와 정확히 동일하게 동작합니다 $0
. 왜냐하면 및 변수 Name
는 정의되지 않았고 and에 대한 숫자 값이 있는 정의되지 않은 변수 (적어도 and 에 대해서는 ) 에서 연산자는 단순히 인수를 숫자로 변환하기 때문입니다. 다른 구현은 오류와 함께 종료될 수 있습니다(이 동작은 표준에 지정되어 있지 않습니다).Class
School
awk
0
mawk
gawk
$
awk
이 시도:
awk -F ' *= *' '$1~/^(Name|Class|School)$/{
if($1 in a){ for(i in a) delete a[i]; comma = ""; printf ORS }
printf "%s%s= %s", comma, $1, $2; a[$1] = comma = ", "
}
END{if(comma) printf ORS}
' file.txt
Name= Garen, Class= 9C, School= US
Name= Lulu, Class= 4A
Name= Kata, Class= 10D, School= UK
위의 예는 순서에 관계없이 키/값 튜플을 그룹화하려고 시도하며 일반적입니다(작동합니다).같은패턴이 제거된 경우 첫 번째 샘플 입력에서 $1~/.../
) 그러나 이것이 항상 첫 번째이고 항상 존재한다는 것을 안다면 Name
모든 것이 훨씬 쉬워집니다.
awk '/^Name=/{printf "%s%s", nl, $0; nl=ORS}
/^(Class|School)=/{printf ", %s", $0}
END{if(nl) printf ORS}' /tmp/file.txt