awk의 후루룩 모드?

awk의 후루룩 모드?

sedawk, 또는 perl -n입력 처리 와 같은 도구기록한 번,기록존재하다철사기본적으로.

awkwith RS, GNU sedwith -z또는 perlwith 와 같은 일부는 -0ooo다른 레코드 구분 기호를 선택하여 레코드 유형을 변경할 수 있습니다.

perl -n전체 입력(여러 파일을 전달할 경우 각 개별 파일)을 하나의 파일로 만드는 것이 가능합니다.기록옵션이 있는 경우 -0777(또는 -00377보다 큰 8진수가 뒤따르며, 777이 표준임) 그게 그들이 말하는 거야흡연 모드.

awk이나 다른 메커니즘을 사용하여 RS유사한 작업을 수행 할 수 있습니까? 각각 awk을 처리하는문서내용은 순서가 아닌 순서대로 배열되어 있습니다.철사파일마다?

답변1

단일 문자로 awk처리하는지 (기존 구현에서와 같이) 정규 표현식으로 처리하는지(like 또는 do) 에 따라 다양한 접근 방식을 취할 수 있습니다 . 빈 파일은 건너뛰는 경향이 있기 때문에 고려하기 어렵습니다 .RSawkgawkmawkawk

gawk, 또는 mawk정규 표현식이 될 수 있는 다른 awk구현 입니다 RS.

이러한 구현에서( 의 경우 mawk일부 운영 체제(예: Debian)는 대신 매우 오래된 버전을 릴리스합니다.@ThomasDickey가 관리하는 최신 버전), RS단일 문자가 포함된 경우 레코드 구분 기호는 해당 문자이고, 비어 있으면 awk단락 모드로 들어가고 RS, RS그렇지 않으면 정규식으로 처리됩니다.

해결책은 일치가 불가능한 정규식을 사용하는 것입니다. 일부는 x^또는 $x( x시작 전 또는 끝 후)를 좋아합니다. 그러나 일부는 (특히 gawk) 다른 것보다 더 비쌉니다. 지금까지 나는 이것이 ^$가장 효과적인 방법이라는 것을 알았습니다. 빈 입력만 일치할 수 있지만 일치하는 항목이 없습니다.

그래서 우리는 이렇게 할 수 있습니다:

awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...

그러나 빈 파일을 건너뛴다는 점에 유의하세요(반대 perl -0777 -n). GNU는 awk코드를 명령문에 넣어 ENDFILE이 문제를 해결할 수 있습니다. 그러나 BEGINFILE 문에서도 이를 재설정해야 합니다 $0. 그렇지 않으면 빈 파일을 처리한 후에 재설정되지 않습니다.

gawk -v RS='^$' '
   BEGINFILE{$0 = ""}
   ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...

전통적인 awk구현, POSIXawk

이는 단지 하나의 문자이고 /도 RS없고 변수도 없으며 일반적으로 NUL 문자를 처리할 수 없습니다.BEGINFILEENDFILERT

RS='\0'어쨌든 NUL 바이트를 포함하는 입력을 처리할 수 없기 때문에 를 사용하면 작동할 것이라고 생각할 수도 있지만 , 그렇지 않습니다. RS='\0'레거시 구현에서는 로 처리됩니다 RS=. 이것이 단락 모드입니다.

한 가지 해결책은 입력에서 찾을 수 없는 문자(예: )를 사용하는 것입니다 \1. 멀티바이트 문자 로케일에서는 $'\U10FFFE'UTF-8 로케일의 문자 와 같이 할당되지 않은 문자나 비문자를 형성하기 때문에 발생할 가능성이 없는 바이트 시퀀스로 설정할 수도 있습니다 . 하지만 완벽한 방법은 아니며 빈 파일에 문제가 있습니다.

또 다른 해결책은 전체 입력을 변수에 저장하고 최종 END 문에서 처리하는 것입니다. 즉, 한 번에 하나의 파일만 처리할 수 있습니다.

awk '{content = content $0 RS}
     END{$0 = content
       printf "%s: <%s>\n", FILENAME, $0
     }' file

이는 다음과 같습니다 sed.

sed '
  :1
  $!{
   N;b1
  }
  ...' file1

이 접근 방식의 또 다른 문제점은 파일이 개행 문자로 끝나지 않고 비어 있지 않은 경우 $0파일이 여전히 끝에 임의로 추가된다는 것입니다( 위 코드에서 대신 를 gawk사용하면 됩니다 ). 한 가지 장점은 /에 파일의 줄 수를 기록 한다는 것입니다 .RTRSNRFNR

한 번에 여러 파일을 처리하려면 한 가지 방법은 단일 명령문에서 모든 파일을 수동으로 읽는 것입니다 BEGIN(여기서는 70년대 API를 사용하는 Solaris awk가 아니라 POSIX를 가정)./bin/awk

awk -- '
  BEGIN {
    for (i = 1; i < ARGC; i++) {
      FILENAME = ARGV[i]
      $0 = ""
      while ((getline line < FILENAME) > 0)
        $0 = $0 line "\n"

      # actual processing here, example:
      print i". "FILENAME" has "NF" fields and "length()" characters."
    }
  }' *.txt

후행 개행에 대한 동일한 경고입니다. 이 파일의 장점은 =문자가 포함된 파일 이름을 처리할 수 있다는 것입니다.

관련 정보