다음 내용이 포함된 텍스트 파일이 있습니다.
제목 1 A1
제목 3 A3
제목 4 A4
제목 5 A5
제목 1 B1
제목 2 B2
제목 5 B5
제목 1 C1
제목 2 C2
제목 4 C4
제목 5 C5
타이틀 1 D1
타이틀 2 D2
타이틀 3 D3
나는 다음과 같은 출력을 원합니다 :
title1 title2 title3 title4 title5
A1 A3 A4 A5
B1 B2 B5
C1 C2 C4 C5
D1 D2 D3
AWK를 사용하여 코드를 작성하는 방법을 알려주실 수 있나요?
미리 감사드립니다!
답변1
공백(또는 ":")만으로 구분되도록 데이터를 변경할 수 있는 경우 다음 awk 프로그램이 이를 수행할 수 있습니다. 레이아웃을 완벽하게 만들기 위해 조정해야 할 수도 있습니다.
BEGIN { i = 1; }
$1 != "" { C[$1] = $1; X[$1,i] = $2 ; next; }
{ i++; }
END {
asort(C);
for ( k in C ) printf " %8s\t", C[k];
printf "\n";
for ( j = 1; j <= i; j++ ) {
for ( k in C ) printf "%8s\t",X[C[k],j];
printf "\n";
}
}
답변2
awk -f transpose_rows_to_cols.awk /tmp/1
title1 title2 title3 title4 title5
A1 A3 A4 A5
B1 B2 B5
C1 C2 C4 C5
D1 D2 D3
추신. 터미널에서 포맷하면 됩니다.
스크립트 -
#!/usr/bin/awk -f
BEGIN {
printf("title1\ttitle2\ttitle3\ttitle4\ttitle5\n");
a["title1"] = a["title2"]= a["title3"]= a["title4"]= a["title5"] = ""
}
{
if ($0 !~ /^$/) {
if ($0 ~ /:/) {FS=":"; $0=$0} else {FS=" "; $0=$0}
a[$1]=$2
} else {
printf("%s\t%s\t%s\t%s\t%s\n", a["title1"], a["title2"], a["title3"], a["title4"], a["title5"])
a["title1"] = a["title2"]= a["title3"]= a["title4"]= a["title5"] = ""
}
}
END{
printf("%s\t%s\t%s\t%s\t%s\n", a["title1"], a["title2"], a["title3"], a["title4"], a["title5"])
}
답변3
이 답변은 다음을 기반으로 합니다.Ralph Rehnquist의 답변, 하지만
- 열은 헤더별 알파벳 순서가 아닌 사용자가 지정한 순서로 출력되어야 한다고 가정합니다.
- 데이터 값은 여러 단어가 허용됩니다.
Ralph의 답변과 마찬가지로 제목이 콜론이 아닌 공백으로 데이터와 분리되어 있다고 가정합니다.
목표 1을 달성하려면 입력이 원하는 순서대로 모든 헤더(수반되는 데이터 없음)를 포함하는 섹션으로 시작해야 합니다.
BEGIN { i = 0; j= 0; }
$1 != "" { if (i==0) C[++j] = $1; else { label = $1; $1 = ""; X[label,i] = $0; } next; }
{ i++; }
END {
for ( k in C ) printf " %8s\t", C[k];
printf "\n";
for ( j = 1; j <= i; j++ ) {
for ( k in C ) printf "%8s\t", X[C[k],j];
printf "\n";
}
}
는 i
으로 초기화 0
되고 해당 i==0
사례는 특별히 처리됩니다. 헤더만 캡처되고(이것이 있어야 하는 유일한 것이므로) 헤더는 값이 아닌 C
증분 정수( )로 인덱스된 배열에 저장됩니다. j
헤더 자체의. 그렇지 않으면 데이터를 캡처합니다.
$1 = "";
행의 첫 번째 필드를 제거하고 $0
다른 모든 필드를 연결하여 다시 작성합니다. (이로 인해 필드 사이에 여러 공백이 손실됩니다. 이는 약간의 작업으로 수정될 수 있습니다.) 데이터 배열에 대한 인덱스로 사용할 수 있도록 값을 변수 $1
에 저장합니다 .label
X
예를 들어 다음 입력은 다음과 같습니다.
name
address
phone
height
weight
name John Lennon
phone 123
height 6' 1"
weight 180
name Sir Paul M.
address Liverpool
weight 175
name George
address 42 Main St.
height 71"
weight 185 lbs
name Ringo Starr
address Penny Lane
phone 456 789
다음 출력을 생성합니다.
name address phone height weight
John Lennon 123 6' 1" 180
Sir Paul M. Liverpool 175
George 42 Main St. 71" 185 lbs
Ringo Starr Penny Lane 456 789
값이 15자 이상이면 해당 열이 꺼집니다. 이는 개선될 수 있습니다.