awk 명령 루프

awk 명령 루프
awk '{print $1 ,": "  $3}' Src.txt | column -t
awk '{for(x=2;$x;++x) print $1, $x "\n"}'  Src.txt | column -t

이 명령은 작동하지만 형식이 올바르지 않습니다. 첫 번째와 두 번째 열만 인쇄할 수 있거나 첫 번째 열을 인쇄한 다음 두 번째와 세 번째 열을 인쇄할 수 있지만 원하는 결과는 다음과 같습니다.

column 1 column 2
column 1 column 3
column 1 column 4 .....

예:

Col1  a b c
Col2  1 2 3  
col3  x y z

산출

Col1 a
Col2 b
Col3 c

Col1 b
col2 2
Col3 y

Col1 c
Col2 3
Col3 z

어쩌면 적절한 루프를 추가해야 할까요?

답변1

awk가 작동하는 방식은 기본적으로 각 항목을 반복하는 것입니다.철사텍스트를 입력하고 공백으로 구분된 각 항목을 필드로 분할합니다. 이 경우 관심 있는 필드는 $2, $3 및 $4입니다. 이제 각 행의 각 $2 필드를 목록에 저장한 다음 인쇄할 수 있다면 어떨까요? 이것이 바로 배열이 도움이 될 수 있는 부분입니다.

awk 코드의 본문을 하나의 큰 while 루프로 생각하면 필드 2, 3, 4를 적절한 배열로 분리할 수 있습니다. 배열은 각 행에 대해 채워집니다. 따라서 행을 반복할 때 기본적으로 모든 것을 열(배열)로 정렬합니다. 완료되면 "Column#" 텍스트를 추가하는 동안 루프를 통해 각 열(배열)을 개별적으로 인쇄할 수 있습니다.

$ awk '{ array1[NR]=$2;array2[NR]=$3;array3[NR]=$4} END{for(i=1;i<=NR;i++){print "Column"i" "array1[i]};printf "\n";for(i=1;i<=NR;i++){print "Column"i" "array2[i]}; printf"\n"; for(i=1;i<=NR;i++){print "Column"i" "array3[i] };printf "\n" }' columns.txt           
Column1 a
Column2 1
Column3 x

Column1 b
Column2 2
Column3 y

Column1 c
Column2 3
Column3 z

물론 이렇게 긴 줄은 사용하기가 좀 어색합니다. 우리는 모든 것을 스크립트에 넣을 수 있습니다:

#!/usr/bin/awk -f

{ array1[NR]=$2;array2[NR]=$3;array3[NR]=$4 } 

END{
  for(i=1;i<=NR;i++){
     print "Column"i" "array1[i]};printf "\n";
   for(i=1;i<=NR;i++){
     print "Column"i" "array2[i]}; printf"\n"; 
   for(i=1;i<=NR;i++){
     print "Column"i" "array3[i] };printf "\n" 
}

스크립트를 호출하고 columnate.awk권한을 실행 가능으로 변경한 chmod +x columnate.awk후 텍스트 파일을 인수로 사용하여 실행합니다.

$ ./columnate.awk columns.txt                                                                                                                          
Column1 a
Column2 1
Column3 x

Column1 b
Column2 2
Column3 y

Column1 c
Column2 3
Column3 z

관련 정보