awk를 사용하여 열(NF)과 행 번호(NR)가 포함된 멋진 테이블 형식을 인쇄하는 방법은 무엇입니까?

awk를 사용하여 열(NF)과 행 번호(NR)가 포함된 멋진 테이블 형식을 인쇄하는 방법은 무엇입니까?

견본

wolf@linux:~$ awk {print} file.txt 
a b
b c
c d
wolf@linux:~$ 

데이터가 매우 작기 때문에 이 작업은 쉽습니다.

wolf@linux:~$ awk 'BEGIN {print "  " 1 " " 2} {print NR,$0}' file.txt
  1 2
1 a b
2 b c
3 c d
wolf@linux:~$ 

더 큰 데이터를 위한 유사한 솔루션이 있습니까? 헤더를 수동으로 인쇄하는 대신 부분적 for loop으로 같은 것을 사용할 생각입니다.BEGIN {print " " 1 " " 2}

답변1

BEGIN부분은 입력 파일이 열리기 전에 실행되므로 for loop입력의 첫 번째 줄을 아직 읽지 않았기 때문에 There를 실행해도 아무 소용이 없으므로 반복할 필드 수를 알 수 없습니다. 하나를 추가하지 않는 한 getline그것은 완전히 다른 웜 캔입니다 (참조http://awk.freeshell.org/AllAboutGetline).

awk필드 콘텐츠를 생성한 다음 공백을 사용하여 형식을 지정 합니다 column. 예를 들면 다음과 같습니다.

$ awk '
    NR==1 { for (i=1; i<=NF; i++) printf " %s", i; print "" }
    { print NR, $0 }
' file  | column -s' ' -t
   1  2
1  a  b
2  b  c
3  c  d

입력 파일에 필드 사이에 여러 개의 공백이나 탭이 있는 경우 awk 스크립트의 마지막 줄 { print{ $1=$1; print.

답변2

tbl필요한 스키마를 기반으로 테이블을 생성하는 groff 코드를 생성하는 groff 래퍼를 사용하여 테이블을 생성할 수 있습니다 .

여기에서는 데이터를 기반으로 awk 유틸리티를 사용하여 groff 조판 유틸리티에 대한 코드를 생성하는 tbl 유틸리티에 대한 코드를 동적으로 생성합니다.

< file \
awk '
  BEGIN {
    OFS = "@"
    print ".TS"
    print "box,tab(", ");"
  }

  !NF {next}

  NR==1 {
    fx(" ", "c", "c", ".")
    fx(OFS) 
  }

  { $1 = NR OFS $1 };1

  END { print ".TE" }

  function fp(str, sep) {
    printf "%s%s", sep, str
  }

  function fx(sep, a, b, c,   i) {
    fp(a)
    for (i=1; i<=NF; i++)
      fp(b""?b:i, sep)
    fp("\n", c)
  }
' - | tbl - | groff -Tascii | grep .

산출:

+----------+
|    1   2 |
|1   A   B |
|2   B   C |
|3   C   D |
+----------+

답변3

for 루프를 사용하여 필드를 반복할 수 있습니다. NR은 현재 행 번호이고 NF는 해당 특정 행의 필드 수입니다.

{   printf ("%4d", NR);
    for (f = 1; f <= NF; ++f) printf (" %-6s", $f);
    printf ("\n");
}

헤더의 경우 첫 번째 행에서 표시해야 하는 열 수를 찾을 때까지 기다려야 합니다. 그래서 이것은앞으로이전 코드. 필드의 내용을 나타내는 $f가 아니라 f 자체를 레이블로 인쇄합니다.

NR == 1 {   printf ("%4d", NR);
    for (f = 1; f <= NF; ++f) printf (" %-6s", f);
    printf ("\n");
}

정렬을 유지하려면 최대 필드 너비를 찾아야 합니다. 각 %-6은 "왼쪽 정렬되고 최대 6자의 공백으로 채워지는 문자열 필드"를 의미합니다.

편집: 고급 버전의 경우 모든 데이터를 [NR, NF]로 인덱싱된 2D 배열에 저장하고 END 블록으로 출력할 수 있습니다. 그런 다음 두 가지 작업을 더 수행할 수 있습니다.

(1) 각 열에 대해 셀의 최대 너비를 찾고 열의 실제 너비를 사용하여 %-10s 형식을 수정합니다.

(2) 각 열에 대해 모두 숫자인 경우 해당 %s를 수정하여 값을 오른쪽 정렬합니다.

관련 정보