print 문을 사용한 awk 내부 옵션

print 문을 사용한 awk 내부 옵션

최신 버전의 awk에는 -i 옵션과 유사한 내부 작업을 inplace수행하는 옵션이 있습니다 . 그러나 나는 그 진술과 함께 작동하도록 sed할 수 없습니다 . print내 예를 살펴 보겠습니다. 테스트 파일의 내용은 다음과 같습니다.

11 aa
22 bb
root@localhost:~# cat test
11 aa
22 bb

를 사용하지 않으면 -i inplace콘솔에서 원하는 결과를 얻을 수 있습니다.

root@localhost:~# awk 'BEGIN{print "begin"} $1=="11"{print "111" $2; next} 1; END{print "end"}' test
begin
111aa
22 bb
end

을 추가하면 -i inplace이것이 내가 얻는 것입니다.

root@localhost:~# awk -i inplace 'BEGIN{print "begin"} $1=="11"{print "111" $2; next} 1; END{print "end"}' test
begin
end
root@localhost:~# cat test
111aa
22 bb
root@localhost:~#

코드를 개선하고 원하는 것을 얻으려면 어떻게 해야 합니까?

고쳐 쓰다


내 awk 버전은 4.1.1.

root@localhost:~# awk --version
GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2-p3, GNU MP 6.0.0)
Copyright (C) 1989, 1991-2014 Free Software Foundation.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
root@localhost:~#

업데이트 2


root@localhost:~# awk --version
GNU Awk 4.1.2, API: 1.1
Copyright (C) 1989, 1991-2015 Free Software Foundation.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
root@localhost:~# cat file
11 aa
22 bb
root@localhost:~# awk 'BEGIN{print "begin"} $1=="11"{print "111" $2; next} 1; END{print "end"}' file
begin
111aa
22 bb
end
root@localhost:~# awk -i inplace 'BEGIN{print "begin"} $1=="11"{print "111" $2; next} 1; END{print "end"}' file
begin
end
root@localhost:~# cat file
111aa
22 bb
root@localhost:~#

답변1

파일에 인쇄하는 시작과 끝은 BEGIN 대신 BEGINFILE, END 대신 ENDFILE을 사용하면 될 것 같습니다.

적어도 이것은 cygwin에서 작동합니다.

Rob@Rob-PC /cygdrive/c/tmp
$ awk --version
GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2, GNU MP 6.0.0)
Copyright (C) 1989, 1991-2014 Free Software Foundation.


Rob@Rob-PC /cygdrive/c/tmp
$ echo "11 aa
22 bb" > test

Rob@Rob-PC /cygdrive/c/tmp
$ awk -i inplace 'BEGINFILE{print "begin"} $1=="11"{print "111" $2; next} 1; ENDFILE{print "end" >> "test"}' test

Rob@Rob-PC /cygdrive/c/tmp
$ cat test
begin
111aa
22 bb
end

답변2

BEGINEND파일이 처리되기 전과 파일이 완전히 처리된 후에 루프가 실행됩니다. -i inplace파일 작업을 할 때만 의미가 있습니다 . 소스 코드를 확인하지 않고는 확실히 알 수 없지만, 따라서 여기에서는 작동 BEGIN하지 않는 것이 END합리적인 것 같습니다 .

이미 제안했듯이 이것이 무엇 BEGINFILEENDFILE위한 것인지입니다. 설정에서 이것이 작동하지 않으면 해결 방법을 사용해야 합니다. 첫 번째 줄을 일치시키는 것은 쉽지만( if(NR==1){print "begin"}), 마지막 줄을 일치시키는 것은 조금 더 까다롭습니다. 사용할 수 있는 몇 가지 기술은 다음과 같습니다.

  1. 다른 도구를 사용하여 시작선과 끝선을 추가합니다.

    perl -i -007ne 'print "begin\n${_}end\n"' file &&
        awk -i inplace '$1=="11"{print "111" $2; next}1;' file
    

    또는

    printf "begin\n%s\nend" "$(cat file)" 
    
  2. awk"시작" 에 대해 나중에 "끝"을 추가합니다.

    awk -i inplace  'NR==1{print "begin"}$1=="11"{print "111" $2; next}1;' file && 
        echo "end" >> file
    
  3. 이해하기 쉬운 도구를 사용하여 모든 작업을 수행하십시오 eof. Perl의 -a스위치는 다음과 같이 작동합니다 awk. 공백의 필드를 @F배열로 분할합니다. 마찬가지로 awk-F스위치를 사용하면 필드 구분 기호를 설정할 수 있습니다. -i현재 위치에서 파일 편집을 켭니다 .

    perl -i -lane '$.==1 && print "begin"; eof && print "end"; 
                   if($F[0]=="11"){print "111$F[0] $F[1]"; next} print;' file
    

관련 정보