sed + 첫 번째 일치 또는 두 번째 일치에서 문자 삭제

sed + 첫 번째 일치 또는 두 번째 일치에서 문자 삭제

다음 sed 구문은 "모두 부여 필요" 줄에서 "#"을 제거합니다.

   sed 's/#\([[:space:]]*Require all granted\)/ \1/' graphite-web.conf

   #<IfModule mod_authz_core.c>
   #    # Apache 2.4
   #    Require local
   #    Order Allow,Deny
   #    Allow from All
        Require all granted
   #</IfModule>
   #<IfModule !mod_authz_core.c>
   #    # Apache 2.2
        Require all granted
   #    Order Allow,Deny
   #    Deny from all
   #    Allow from All
   #    Allow from ::1
   #</IfModule>

첫 번째 일치 항목에서 "#"을 제거하도록 sed 구문을 어떻게 변경합니까? 아니면 두 번째 게임?

예상 출력:

   #<IfModule mod_authz_core.c>
   #    # Apache 2.4
   #    Require local
   #    Order Allow,Deny
   #    Allow from All
        Require all granted
   #</IfModule>
   #<IfModule !mod_authz_core.c>
   #    # Apache 2.2
   #    Require all granted
   #    Order Allow,Deny
   #    Deny from all
   #    Allow from All
   #    Allow from ::1
   #</IfModule>

또는

   #<IfModule mod_authz_core.c>
   #    # Apache 2.4
   #    Require local
   #    Order Allow,Deny
   #    Allow from All
   #    Require all granted
   #</IfModule>
   #<IfModule !mod_authz_core.c>
   #    # Apache 2.2
        Require all granted
   #    Order Allow,Deny
   #    Deny from all
   #    Allow from All
   #    Allow from ::1
   #</IfModule>

답변1

awk대신 사용

$ cat ip.txt 
   #    Allow from All
   #    Require all granted
   #    # Apache 2.2
   #    Require all granted
   #    Order Allow,Deny
   #    Require all granted
   #    Order Deny

$ awk '/#[[:space:]]*Require all granted/ && ++c==1{sub("#", " ")} 1' ip.txt
   #    Allow from All
        Require all granted
   #    # Apache 2.2
   #    Require all granted
   #    Order Allow,Deny
   #    Require all granted
   #    Order Deny

$ awk '/#[[:space:]]*Require all granted/ && ++c==2{sub("#", " ")} 1' ip.txt
   #    Allow from All
   #    Require all granted
   #    # Apache 2.2
        Require all granted
   #    Order Allow,Deny
   #    Require all granted
   #    Order Deny

$ awk '/#[[:space:]]*Require all granted/ && ++c>1{sub("#", " ")} 1' ip.txt
   #    Allow from All
   #    Require all granted
   #    # Apache 2.2
        Require all granted
   #    Order Allow,Deny
        Require all granted
   #    Order Deny

당신은 또한 볼 수 있습니다awk는 변경 사항을 제자리에 저장합니다.


또는 다음을 사용하십시오.perl

$ # for inplace editing, use perl -i -pe
$ perl -pe 's/#/ / if /#\s*Require all granted/ && ++$c==1' ip.txt
   #    Allow from All
        Require all granted
   #    # Apache 2.2
   #    Require all granted
   #    Order Allow,Deny
   #    Require all granted
   #    Order Deny

답변2

또는 sed방법:

sed ':a;N;$!ba;s/#\([[:space:]]*Require all granted\)/ \1/2' graphite-web.conf

입력 파일에 다음이 포함된 경우:

#<IfModule mod_authz_core.c>
   #    # Apache 2.4
   #    Require local
   #    Order Allow,Deny
   #    Allow from All
   #    Require all granted
   #</IfModule>
   #<IfModule !mod_authz_core.c>
   #    # Apache 2.2
   #    Require all granted
   #    Order Allow,Deny
   #    Deny from all
   #    Allow from All
   #    Allow from ::1
   #</IfModule>

출력은 다음과 같습니다:

#<IfModule mod_authz_core.c>
   #    # Apache 2.4
   #    Require local
   #    Order Allow,Deny
   #    Allow from All
   #    Require all granted
   #</IfModule>
   #<IfModule !mod_authz_core.c>
   #    # Apache 2.2
        Require all granted
   #    Order Allow,Deny
   #    Deny from all
   #    Allow from All
   #    Allow from ::1
   #</IfModule>

이 모드는 :a;N;$!ba;파일 끝(예: while 루프) 이전의 모든 행을 읽고 s///2eof가 도착한 후 두 번째 발생에서 교체를 수행합니다.

당신이 읽은 sed 태그에 대한 최고의 설명:a;$!N;은 무슨 뜻인가요? sed 명령에서?

비슷한 주제를 읽고sed를 사용하여 n번째 문자열을 바꾸는 방법

답변3

스트림에서 작동하도록 설계되었습니다. 원하는 것을 달성하는 쉬운 방법은 다음을 사용하는 것입니다 ed.

ed -s graphite-web.conf <<<$'/Require all/s/#/ /\nw'

업데이트: 자세히 설명할 수 있지만 ed이건페이지ed더 자세히 설명하고 널리 사용됩니다.

이 줄에 대한 나의 해석은 다음과 같습니다.

-s그것은 꽤 의미합니다. 우리가 무엇을 바꾸었는지 보여주지 마세요.

그런 다음 herestring을 사용 하고 백슬래시 문자 조합이 확장되는 <<<ANSI C 형식의 인용을 적용합니다 . 새로운 줄을 추가하고 파일에 쓴다는 의미입니다.$''\nw

답변4

버전 은 다음과 같습니다 ... 변경할 발생 횟수를 나타내는 숫자로 ex쉘 변수를 설정합니다 (예: 이 명령을 사용하면 패턴의 두 번째 발생이 수정됩니다)...xx=2

그러면 입력 파일이 업데이트됩니다.

ex +'/#\(\s*Require all granted\)/|1' +"norm ${x}n" +'s// \1/|wq' file 

이는 파일을 수정하지 않지만 수정된 버전을 인쇄하는 파이프 변형입니다.표준 출력:

cat file | ex +'/#\(\s*Require all granted\)/|1' +"norm ${x}n" +'s// \1/' +'%p|q!' /dev/stdin

세부 사항:

대화형으로 실행되지 않는 경우에는 ex기본적으로 일괄 처리의 명령줄 모드 중심 버전이므로 vim많은 콘텐츠가 vim사용자에게 친숙해야 합니다.

  • /#\(\s*Require all granted\)/|1- 패턴을 검색하고 1번째 줄 "Reset"으로 이동합니다.
  • norm ${x}nn- 패턴 타임 x의 마지막 발생위치 로 이동
  • s// \1/|wq- 현재 줄만 교체하고 쓰기 종료

관련 정보