다음과 같은 로그 파일을 생성하는 프로그램이 있습니다.
Player: 9.8.7.6.5.4.3.2.1 () Item: 10/gold/tool//onehanded///, 15/gold/tool//twohanded
Player: 8.7.6.5.4.3.2.1.9 () Item: 20/diamond/tool//twohanded///
Player: 7.6.5.4.3.2.1.9.8 () Item: 30/copper/tool//onehanded///, 36/gold/tool//twohanded///
Player: 6.5.4.3.2.1.9.8.7 () Item: 40/gold/tool//twohanded///
Player: 5.4.3.2.1.9.8.7.6 () Item: 50/gold/tool//onehanded///, 55/gold/tool//twohanded///
Player: 4.3.2.1.9.8.7.6.5 () Item: 10/gold/tool//onehanded///, 12/diamond/tool//twohanded///
...
로그 파일이 계속 나타납니다. 내가 필요한 것은 모든 출력을 인쇄하는 것입니다플레이어다음 도구를 가지고금, 와 함께ID도구의. 예를 들어 다음이 필요합니다.
Player: 9.8.7.6.5.4.3.2.1;10;15
Player: 7.6.5.4.3.2.1.9.8;36
Player: 6.5.4.3.2.1.9.8.7;40
Player: 5.4.3.2.1.9.8.7.6;50;55
Player: 4.3.2.1.9.8.7.6.5;10
보시다시피 플레이어 8.7.6.5.4.3.2.1.9는 금 도구가 없기 때문에 출력에 포함되지 않습니다.
지금까지 내 코드는 다음과 같습니다.
grep "/gold" file | awk -F '[()]' '{print $1}'
다음을 생성합니다.
Player: 9.8.7.6.5.4.3.2.1
Player: 7.6.5.4.3.2.1.9.8
Player: 6.5.4.3.2.1.9.8.7
Player: 5.4.3.2.1.9.8.7.6
Player: 4.3.2.1.9.8.7.6.5
이 문제를 해결하려면 위 코드에 무엇을 추가해야 합니까?
답변1
GNU awk 사용:
$ gawk -F' \\(\\) ' '
/gold\/tool/ {
items = $2; ids="";
while(match(items,/([0-9]+)\/gold\/tool/,a)) {
ids = ids ";" a[1];
items = substr(items,RSTART+RLENGTH+1)
}
print $1 ids
}' file
Player: 9.8.7.6.5.4.3.2.1;10;15
Player: 7.6.5.4.3.2.1.9.8;36
Player: 6.5.4.3.2.1.9.8.7;40
Player: 5.4.3.2.1.9.8.7.6;50;55
Player: 4.3.2.1.9.8.7.6.5;10
답변2
Steeldriver에서 영감을 얻었으며 어쩌면 더 간단할 수도 있습니다.
gawk '{
g=0
for (i=5; i<=NF; i++) {
if (match($i, /^([0-9]+)\/gold/, a)) {
if (g++ == 0) printf "%s %s", $1, $2
printf ";%s", a[1]
}
}
if (g > 0) printf "\n"
}' file
답변3
GNU sed는 확장 정규식 모드이므로 -E
정규식 작성이 덜 까다로워집니다. 사용되는 방법은 관심 없는 선, 즉 금을 포함하지 않는 선을 즉시 삭제하는 것입니다. 그런 다음 금메달이 아닌 메달은 모두 제거하고 금메달 앞의 숫자만 제거합니다.
$ sed -Ee '
s/\s*[(][)]\s*/\n/
\|\n.*[0-9]/gold/|!d
:a
/\n$/!{
\|\n([0-9]+)/gold/\S+\s*|{
s//;\1\n/;ba
}
s|\n\S+\s*|\n|;ba
}
s/(^\s*|\s*$)//g
' file.log
Perl은 작업을 간단하게 만듭니다.
$ perl -F'[(][)]' -lane '
(my $p = $F[0]) =~ s/(^\s*|\s*$)//g;
my @A = $F[1] =~ m[\D(\d+)/gold/]g;
print join ";", $p, @A if @A;
' file.log
결과:
Player: 9.8.7.6.5.4.3.2.1;10;15
Player: 7.6.5.4.3.2.1.9.8;36
Player: 6.5.4.3.2.1.9.8.7;40
Player: 5.4.3.2.1.9.8.7.6;50;55
Player: 4.3.2.1.9.8.7.6.5;10