awk를 사용하여 7개의 파일을 한 줄씩 연결합니다.

awk를 사용하여 7개의 파일을 한 줄씩 연결합니다.

동일한 줄 수의 파일이 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]iia[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)
}

관련 정보