동일한 줄 수의 파일이 7개(또는 8개 등) 있습니다.
파일1
1.001
1.002
1.003
1.004
파일2
2.001
2.002
2.003
2.004
파일3
3.001
3.002
3.003
3.004
등.
원하는 출력:
1.001;2.001;3.001;4.001;5.001;6.001;7.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004
awk에서 짧은 스크립트로 어떻게 수행합니까?
답변1
steeldriver가 말했듯이 이를 수행하는 합리적인 방법은 다음과 같습니다 paste
.
$ paste -d';' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004
그러나 반드시 사용해야 하는 경우 awk
:
$ awk '{a[FNR]=a[FNR](FNR==NR?"":";")$0} END{for (i=1;i<=FNR;i++) print a[i]}' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004
awk 스크립트는 모든 데이터를 메모리에 유지합니다. 파일이 크면 문제가 될 수 있습니다. 그러나 이 작업에는 paste
어쨌든 더 좋고 간단합니다.
작동 원리
이 스크립트에는 line 의 출력이 되는 a
배열이 있습니다 . 후속 파일 각각을 읽으면서 line 의 끝에 새 정보를 추가합니다 . 파일 읽기를 마친 후 . 더 자세하게:a[i]
i
i
a[i]
a
a[FNR]=a[FNR](FNR==NR?"":";")$0
FNR
는 우리가 읽고 있는 현재 파일의 줄 번호이고$0
해당 줄의 내용입니다. 이 코드는$0
의 끝에 추가됩니다a[FNR]
. 아직 첫 번째 파일을 읽고 있는 경우를 제외하고 앞에 세미콜론을 넣습니다$0
. 이는 복잡해 보이는 삼항문을 사용하여 수행됩니다:(FNR==NR?"":";")
. 이는 실제로 if-then-else 명령일 뿐입니다. 첫 번째 파일, 즉 if 를 읽는 경우FNR==NR
빈 문자열을 반환합니다""
. 그렇지 않은 경우 세미콜론( )을 반환합니다;
.END{for (i=1;i<=FNR;i++) print a[i]}
모든 파일 읽기를 마친 후에는 array 에 축적된 데이터를 인쇄합니다
a
.
답변2
POSIX 어크; 이는 임의의 양의 파일에서 작동하며 파일의 줄 수가 동일할 필요도 없습니다. 스크립트는 모든 파일이 줄을 벗어날 때까지 계속 진행됩니다.
BEGIN {
do {
br = ch = 0
while (++ch < ARGC)
if (getline < ARGV[ch]) {
printf ch < ARGC - 1 ? $0 ";" : $0 RS
br = 1
}
} while (br)
}