검색, 삽입, 이동 및 삽입

검색, 삽입, 이동 및 삽입

패턴에 대해 파일의 모든 레코드(레코드는 빈 줄로 정의됨)를 검색하고 싶습니다 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

예상 출력

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

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7

#AGE 9
NAME#AAAA
STD 4
AGE NIL

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

또한 그 반대도 필요합니다. 변경 사항을 되돌리기만 하면 됩니다. 이 모든 작업을 AIX 시스템에서 수행하고 있다는 점에 유의하세요.

답변1

ex이는 POSIX 지정 파일 편집 도구의 완벽한 사용 사례입니다.

vi(그런데, 사용해 본 적이 있다면 콜론으로 시작하는 모든 ex입력 이 명령 이라는 사실에 익숙할 것입니다. 이는 의 전신입니다 .)vi:exexvi

printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' x | ex input.txt

파일을 실제로 저장하기 전에 테스트하려면 x파이프 기호 앞의 마지막 기호를 로 변경하면 %p수정된 파일은 저장되지 않지만 수정된 버전은 으로 인쇄됩니다 stdout. 따라서 테스트 명령은 다음과 같습니다.

printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' %p | ex input.txt

설명하다:

printf %s\\nex각 명령 뒤에 줄 바꿈을 추가하여 여러 명령을 입력하는 쉬운 방법을 제공합니다 .

g/regex/전역 명령입니다. 주어진 정규식과 일치하는 각 줄에서 다음 명령을 실행합니다(다음 개행 문자까지).

/AGE/t-패턴과 일치하는 다음 줄을 /AGE/현재 줄 앞의 위치에 복사합니다 NAME#AAAA. 또한 커서를 행의 새 복사본으로 이동합니다(이제 "현재 행"이 됨).

|의 명령 구분 기호입니다 ex.

s/^/#/복사한 줄 AGE앞에 해시태그를 추가하세요 . (또는 방언에 따라 파운드 기호도 있습니다.) ;)

다음 명령은 실제로 두 부분으로 구성됩니다. /AGE/주소는 패턴이 포함된 다음 줄에서 명령이 실행되도록 하고, s/.*/AGE NIL/해당 줄에 있는 내용을 로 바꿉니다 AGE NIL.

x파일에 대한 변경 사항을 저장하고 종료합니다.


변경사항 취소

변경 사항을 취소하려면 다음을 수행합니다.

printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' %p | ex input.txt

그런 다음 변경 사항이 확인되면 실제로 변경 사항을 저장합니다.

printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' x | ex input.txt

설명하다:

이전과 동일한 전역 명령입니다.

NAME으로 시작하는 줄을 선택 #AGE하고 로 시작하는 다음 줄 뒤로 이동하세요 AGE.

선행을 제거합니다 #.

바로 앞의 행 -d(NIL 연령 행)을 삭제합니다.

변경 사항을 인쇄하거나 저장합니다.

답변2

perl -pe 'BEGIN{$/=""} 
          s/^(NAME#AAAA.*\n)(AGE.*?)(\n+)$/#$2\n$1AGE NIL$3/s' ex1

매우 간단한 설명:

For all the registers in input                 |  perl -p
   separator= one or more empty lines          |     BEGIN{$/=""}
do:
  | substitute                                 |     s/
  |   ^(NAME AAAA.*\n)(AGE.*?)(\n+)$           |       regex /
  |    1              2       3                | 
  | by                                         |      /subst. string including
  |   # $2 \n  $1   AGE NIL   $3               |       capture groups/
  |                                            |
  | and print                                  |  ...from option -p

고쳐 쓰다:

NAME#AAAA 대신 변수를 사용할 수 있나요?

perl -pe '
    BEGIN{
       $/=""; 
       $f=shift;  }
    s/^(NAME#$f.*\n)(AGE.*?)(\n+)$/#$2\n$1AGE NIL$3/s' AAAA  ex1

이 버전에서는무늬매개변수(예: "AAAA"):

  • 4행: 명령줄에서 첫 번째 인수("AAAA")를 가져와서 $f에 저장합니다.
  • 5행 : 대체 모드에서 $f를 확장합니다.

관련 정보