패턴에 대해 파일의 모든 레코드(레코드는 빈 줄로 정의됨)를 검색하고 싶습니다 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
:
ex
ex
vi
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\\n
ex
각 명령 뒤에 줄 바꿈을 추가하여 여러 명령을 입력하는 쉬운 방법을 제공합니다 .
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를 확장합니다.