다음 형식의 데이터 파일이 있습니다.
Header:H1
Sub-header:H1S1
Record:R1
Record:R2
Sub-header:H1S2
Record:R5
Record:R6
Sub-header:H1S3
Record:R9
Record:R10
Header:H2
Sub-header:H2S1
Record:R15
Record:R16
Header:H3
Sub-header:H3S1
Record:R25
Record:R26
Sub-header:H3S2
Record:R30
Record:R31
파일이 다음 형식을 갖도록 AWK를 사용하여 이 파일을 처리하고 싶습니다.
H1, H1S1, R1
H1, H1S1, R2
H1, H1S2, R5
H1, H1S2, R6
H1, H1S3, R9
H1, H1S3, R10
H2, H2S1, R15
H2, H2S1, R16
H3, H3S1, R25
H3, H3S1, R26
H3, H3S2, R30
H3, H3S2, R31
어떻게 하나요?
답변1
제목과 부제목을 볼 때 기억한 다음 Record: 줄을 볼 때 (기록 데이터와 함께) 인쇄해야 합니다.
$ awk -F: -v OFS=", " '/^Header:/ { header = $2; next };
/^Sub-header:/ { subheader = $2; next };
/^Record:/ { print header, subheader, $2 }' input.txt
H1, H1S1, R1
H1, H1S1, R2
H1, H1S2, R5
H1, H1S2, R6
H1, H1S3, R9
H1, H1S3, R10
H2, H2S1, R15
H2, H2S1, R16
H3, H3S1, R25
H3, H3S1, R26
H3, H3S2, R30
H3, H3S2, R31
이 next
진술은 작은 최적화입니다.필요$2를 추출하면 다음 입력 줄로 이동하여 스크립트 상단부터 다시 처리를 시작합니다.
이와 같은 스크립트의 경우 성능에 거의 영향을 미치지 않습니다. 그다지 많은 영향을 미치지 않습니다. 많은 수의 패턴을 일치시켜야 하거나 계산을 수행해야 하는 더 복잡한 스크립트의 경우 이는 상당한 영향을 미칠 수 있습니다.
답변2
:
입력 파일에 주변 공백이 없다고 가정하면 다음 awk
프로그램이 작업을 수행합니다.
awk 'BEGIN{FS=":";OFS=","} $1=="Header"{h=$2} $1=="Sub-header"{s=$2} $1=="Record" {print h,s,$2}' input.txt
그러면 먼저 :
필드 구분 기호가 입력으로 설정되고 ,
필드 구분 기호가 출력으로 설정됩니다.
그런 다음 첫 번째 입력 필드의 이름이 and 로 지정될 때마다 최신 헤더와 하위 헤더를 읽고 h
각각 변수에 저장합니다. 행이 발견되면 필드 값과 및 각각에 저장된 값을 인쇄합니다.s
Header
Sub-header
Record
h
s
Sub-header
여기서는 첫 번째 항목 앞에 항상 가 붙는다고 가정합니다 Record
. 빈 자막을 허용하려면 첫 번째 규칙 블록을 다음에서 변경하세요.
$1=="Header"{h=$2}
도착하다
$1=="Header"{h=$2;s=""}
답변3
입력에 태그 값 쌍이 있을 때마다 먼저 해당 맵을 저장할 배열을 생성하는 것이 가장 좋습니다( f[]
아래). 그런 다음 값(이름)으로 주소를 지정하여 값 태그에 액세스/인쇄/비교/수정/모든 값을 지정할 수 있습니다. :
$ cat tst.awk
BEGIN { FS=":"; OFS=", " }
{ f[$1] = $2 }
/^Record/ { print f["Header"], f["Sub-header"], $2 }
$ awk -f tst.awk file
H1, H1S1, R1
H1, H1S1, R2
H1, H1S2, R5
H1, H1S2, R6
H1, H1S3, R9
H1, H1S3, R10
H2, H2S1, R15
H2, H2S1, R16
H3, H3S1, R25
H3, H3S1, R26
H3, H3S2, R30
H3, H3S2, R31