견본
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를 수정하여 값을 오른쪽 정렬합니다.