파일에 나타나는 마지막 단어 바꾸기

파일에 나타나는 마지막 단어 바꾸기

시나리오는 쉘 스크립트에서 마지막으로 나타나는 단어를 주석 처리하고 싶다는 것입니다 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이 답변.

이를 위해서는 tacGNU 도구와 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파일을 내부에서 편집 할 수 있습니다 ( sedBSD에 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//#&/; 이는 가장 최근에 일치된 정규식을 재사용하고 &나중에 줄의 일치하는 부분을 삽입하는 데 사용됩니다)를 삽입합니다 #.

후행 ,pQ명령은 전체 버퍼를 표준 출력으로 인쇄한 다음 무조건 종료됩니다.

답변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

관련 정보