시나리오는 쉘 스크립트에서 마지막으로 나타나는 단어를 주석 처리하고 싶다는 것입니다 sed
.
temp.sh
다음이 있다고 가정해 보겠습니다 .
Abc 123 Abc
Sdf 2
Abc
Abc
Utyr
Qww
Abc
나는 마지막 인스턴스 (줄의 시작 부분에 발생)를 다음과 같이 바꾸고 싶습니다. #Abc
결국 결과는 다음과 같습니다.
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
답변1
파일을 되돌리려면 첫 번째 파일을 주석 처리한 다음 파일을 다시 되돌립니다.
$ tac temp.sh | sed '0,/^Abc/{s/^Abc/#&/}' | tac
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
이는 "라인 0에서 시작하여 첫 번째 라인이 일치할 때까지 계속하고 /^Abc/
해당 라인에서만 이 경우 ( )와 일치하는 항목 Abc
으로 대체함을 의미합니다 . 감사합니다.#
#
Abc
이 답변.
이를 위해서는 tac
GNU 도구와 GNU 구현이 필요합니다 sed
.
원본 파일을 변경하려면 다음을 사용하십시오.
tac temp.sh | sed '0,/^Abc/{s/^Abc/#&/}' | tac > temp1.sh &&
mv temp1.sh temp.sh
또는 Perl에서는:
$ tac temp.sh | perl -pe 'next if $k; $k++ if s/^Abc/#$&/ ' | tac
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
원본 파일을 변경하려면 다음을 사용하십시오.
tac temp.sh | perl -pe 'next if $k; $k++ if s/^Abc/#$&/ ' | tac> temp1.sh &&
mv temp1.sh temp.sh
또는 사용스테판의 순수한 perl
접근 방식또는선행이 깨끗한 sed
사람, 둘 다 -i
원시 파일을 편집하는 데 사용됩니다.
답변2
$ sed -e 'H; $!d' -e 'g; s/\n\(.*\n\)\(Abc\)/\1#\2/' file
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
이는 전체 파일을 예약된 공간으로 읽어 들여 sed
수정한 후 수정된 텍스트를 출력합니다.
처음 두 sed
표현식을 H
합산하고 $!d
각 줄을 예약된 공간에 추가한 후 다음 루프로 점프합니다(입력의 마지막 줄에 있지 않은 경우).
이 g
명령은 마지막 줄에 대해 실행되며 예약된 공간의 내용을 가져옵니다. 그런 다음 교체는 그 안에 있는 초기 줄 바꿈을 제거하고(첫 번째 줄을 빈 예약 공간에 추가) #
마지막 줄 바꿈 앞에 Abc
문자를 삽입합니다 .
우리는 얻을 것을 보장합니다마지막 Abc
줄바꿈 문자 이후에는 .*
욕심이 많기 때문에 최대한 일치하게 됩니다.
-i
파일을 내부에서 편집 할 수 있습니다 ( sed
BSD에 sed
필요한 GNU 사용 -i '.bak'
).
sed -i'.bak' -e 'H; $!d' -e 'g; s/\n\(.*\n\)\(Abc\)/\1#\2/' file
ed
편집자 와 함께 :
$ printf '%s\n' '1;?^Abc?;s//#&/' ,p Q | ed -s file
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
ed
이는 본질적으로 단일 편집 명령을 사용하여 편집을 수행합니다 1;?^Abc?;s//#&/
. 이 명령은 먼저 커서를 파일의 첫 번째 줄( 1
; Abc
문자열이 마지막 줄에 있는 경우 필요함)로 이동한 다음 ^Abc
파일에서 마지막으로 일치하는 정규식( ?^Abc?
)을 검색합니다. 일단 발견되면, #
발견된 줄의 시작 부분에 문자( s//#&/
; 이는 가장 최근에 일치된 정규식을 재사용하고 &
나중에 줄의 일치하는 부분을 삽입하는 데 사용됩니다)를 삽입합니다 #
.
후행 ,p
및 Q
명령은 전체 버퍼를 표준 출력으로 인쇄한 다음 무조건 종료됩니다.
답변3
포함 awk
(파이프 제외):
awk -v str=Abc '
NR==FNR{if ($0 == str) nr_str=NR; next}
{print (FNR == nr_str) ? "#"$0 : $0}
' file file
산출
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
답변4
사용 awk
:
파일을 되돌리려면 then awk
함수를 사용하십시오. sub()
나중에 파일을 다시 반전하면 예상한 출력이 제공됩니다.
$ tac file |
awk '/^Abc/ && (!found){sub(/^Abc/, "#Abc"); found++}1' |
tac
산출
Abc 123 Abc
Sdf 2
Abc
#Abc
Utyr
Qww
파이프가 없는 경우:
$ awk '
BEGIN{rec_rep=""; rec_last=""}
{if (/^Abc/){
if (rec_rep) print rec_rep;
rec_rep = $0;
sub(/^Abc/, "#Abc");
rec_last = $0;
}
else { rec_rep = ((rec_rep) ? rec_rep ORS : "") $0;
rec_last = ((rec_last) ? rec_last ORS : "") $0 }
}
END{print rec_last}' file