패턴을 검색해서 바꾸고 싶어요

패턴을 검색해서 바꾸고 싶어요

패턴에 대해 파일의 모든 레코드(레코드는 빈 줄로 정의됨)를 검색하고 싶습니다 NAME#AAAA. 일치하는 항목이 있으면 #레코드 앞에 하나를 삽입하고 age레코드 끝에 행을 삽입합니다.age NIL

입력 파일:

NAME#AAAA
STD 1
SEC A
AGE 5

NAME#BBBB
STD 2
SEC B
AGE 6


NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
AGE 9


NAME#AAAA
STD 7
SEC A
AGE 12

예상 출력

NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7


NAME#AAAA
STD 4
#AGE 9
AGE NIL


NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL

답변1

Perl의 "단락 모드"는 빈 줄("단락")로 구분된 레코드를 볼 때마다 종종 좋은 솔루션이 됩니다.

$ perl -00lpe 'if(/NAME#AAAA/){s/\bAGE\s/#$&/; s/$/\nAGE NIL/;}' file
NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
#AGE 9
AGE NIL

NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL

설명하다

  • -00: 이는 Perl의 단락 모드를 활성화합니다. 여기서 각 "단락"(공백이 아닌 줄부터 빈 줄까지의 집합)이 "줄"로 처리됩니다.
  • -l: 각 입력 레코드(각 단락)에서 후행 줄 바꿈을 제거하고 print각 호출에 줄 바꿈을 추가합니다. -pe: 주어진 스크립트를 적용한 후 각 입력 레코드를 인쇄합니다 -e.

따라서 이러한 플래그는 perl입력 파일을 읽고 각 레코드에 스크립트를 적용한 다음 결과를 인쇄합니다. 스크립트 자체가 수행하는 작업은 다음과 같습니다.

  • if(/NAME#AAAA/): 이 레코드가 일치하는 경우 NAME#AAAA.
  • s/\bAGE\s/#$&/:은 s/foo/bar/대체 연산자입니다. foo으로 대체됩니다 bar. 여기서는 AGE앞에 붙은 자체로 대체하겠습니다 #. 단어 경계와 일치하며 일치 항목과 같은 항목은 \b제외됩니다 . "무엇이든 일치"를 의미하는 특수 변수입니다. 따라서 으로 대체됩니다 .ADAGE$&s/\bAGE\s/#$&/AGE#AGE
  • s/$/\nAGE NIL/: $레코드의 끝과 일치합니다. 따라서 이를 다른 것으로 대체하면 레코드 끝에 추가됩니다. 이 명령은 AGE NIL일치하는 레코드 끝에 추가됩니다 .

여기의 모든 작업은 대소문자를 구분합니다. 대소문자를 구분하지 않는 일치가 필요한 경우 다음 명령을 사용하십시오.

perl -00lpe 'if(/NAME#AAAA/i){s/\bAGE\s/#$&/i; s/$/\nAGE NIL/i;}' file

관련 정보