다음과 같은 로그 파일이 있습니다.
Bug123:c:SomeComment
Bug222:c:SomeOtherComment
Bug123:c:SecondComment
나는 다음을 만들어야 한다:
Bug123
SomeComment
SecondComment
Bug222
SomeComment
Bash를 사용하면 이 작업을 수행하는 쉬운 방법이 생각나지 않는 것 같습니다. 어떤 아이디어가 있나요?
답변1
$ awk 'BEGIN {FS=":"} {comments[$1][NR]=$3} END {for (bug in comments) { print bug; for (comment in comments[bug]) { print " ",comments[bug][comment] } } } ' /path/to/input
Bug123
SomeComment
SecondComment
Bug222
SomeOtherComment
이는 입력 파일을 읽을 때 다차원 배열을 설정한 다음 "오류"가 나타나는 순서대로 결과 데이터를 반복함으로써 수행됩니다. 약간의 조정을 통해 외부 배열을 정렬하도록 수정할 수 있습니다.
답변2
흥미로운 접근 방식은 다음과 같습니다 vi
(또는 실제로 ex
각 명령의 앞에 콜론을 생략하는 경우).
:%!awk -F: '{a[$1];print} END {for (i in a) {print i}}'
:v/:/m0
:%!sort -st: -k1,1
:%s/^.*:/\t/
설명하다:
Awk 명령은 각 행을 있는 그대로 인쇄하고 파일 끝에 모든 고유한 첫 번째 필드 목록을 덤프합니다.
이 v
명령은 m
모든 줄을 0번 줄(파일의 시작 부분)로 이동합니다.아니요콜론이 없습니다. (즉, 출력의 첫 번째 필드 목록입니다 awk
.)
이 sort
명령은 s
첫 번째 필드를 기준으로 행을 정렬하는 대신 행의 순서를 유지하여 테이블을 정렬합니다. ('제목' 필드를 파일 시작 부분으로 이동했습니다.)
그런 다음 ubstitute 명령은 s
제목이 아닌 각 행의 접두어를 탭 문자로 변경합니다.
귀하가 제공한 입력 결과:
Bug123
SomeComment
SecondComment
Bug222
SomeOtherComment
추가 정보:
:
(콜론)은 -style 명령을 vi
시작하기 위해 입력하는 것입니다 .ex
%
주소 범위입니다ex
. "버퍼(파일)의 모든 라인에 다음 작업/명령을 적용한다"는 의미입니다.
address와 함께 사용하면 !
"필터"가 시작됩니다 ex
. address로 지정된 행은 지정된 외부 명령에 대한 입력으로 공급되고 버퍼에서 해당 명령의 출력으로 대체됩니다.
-F:
Awk 필드 구분자를 설정합니다.
{}
(중괄호)는 Awk에서 실행할 명령을 둘러싸는 데 사용됩니다. 없기 때문에앗중괄호 앞의 주소(작은따옴표 안), 중괄호 안의 연산은 입력의 각 줄에 적용됩니다.
a[$1]
현재 행( )의 첫 번째 필드를 인덱스로 사용하여 $1
배열 요소를 생성합니다 . 라고 표시되지 않기 때문에 = "whatever"
배열 요소에는값하지만 그것은 중요하지 않습니다. 단지 배열에 해당 요소가 포함되기를 원할 뿐입니다.
;
Awk 명령을 종료합니다.
print
현재 행(기본값) 또는 전달된 인수(나중에 표시됨 print i
)를 인쇄하는 Awk 명령입니다.
END
모든 입력(Awk에 대한)이 처리된 후에 수행될 작업 블록(중괄호)을 표시합니다.
이 for
루프는 이름이 지정된 배열의 모든 인덱스를 인쇄합니다 a
. 이는 특별한 순서 없이 중복 항목을 제거하는 로그 파일의 첫 번째 필드입니다.
Awk 명령에 대해서는 이만큼입니다.
이 명령은 전역 명령 과 반대 v
입니다 . 행동을 취하다ex
g
g
모든 라인이 일치어떤 종류의 패턴. v
주어진 패턴과 일치하지 않는 모든 행에 대해 지정된 작업을 수행합니다.
/
시작 및 종료 모드. 이 :
경우.
m
"움직이다"라는 뜻이에요. 따라서 콜론을 포함하지 않는 모든 줄을 파일의 맨 위로 :v/:/m0
이동하십시오 .vi
나머지 명령은 명확해야 합니다. :)
답변3
펄 한줄
perl -MList::Util=uniq -F: -lane '
push @keys, $F[0];
push @{ $comment{$F[0]} }, $F[2];
} END {
for $key (uniq @keys) {
print $key;
print " $_" for @{$comment{$key}};
}
' file