동일한 줄 수의 파일이 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
인 배열이 있습니다 . 각 후속 파일을 읽을 때 행 에 대한 새 정보를 에 추가합니다 . 파일을 읽은 후 에 값을 인쇄합니다 . 더 자세하게: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 명령일 뿐입니다. 첫 번째 파일을 읽는 경우, 즉FNR==NR
빈 문자열을 반환합니다""
. 그렇지 않은 경우 세미콜론이 반환됩니다;
.END{for (i=1;i<=FNR;i++) print a[i]}
모든 파일을 읽었으면 배열에 축적된 데이터가 인쇄됩니다
a
.
답변2
POSIX awk; 이것은 여러 파일에서 작동하며 파일의 줄 수가 같을 필요도 없습니다. 모든 파일이 줄 수를 초과할 때까지 스크립트가 계속 실행됩니다.
BEGIN {
do {
br = ch = 0
while (++ch < ARGC)
if (getline < ARGV[ch]) {
printf ch < ARGC - 1 ? $0 ";" : $0 RS
br = 1
}
} while (br)
}