다음 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///2
eof가 도착한 후 두 번째 발생에서 교체를 수행합니다.
당신이 읽은 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
쉘 변수를 설정합니다 (예: 이 명령을 사용하면 패턴의 두 번째 발생이 수정됩니다)...x
x=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}n
n
- 패턴 타임x
의 마지막 발생위치 로 이동s// \1/|wq
- 현재 줄만 교체하고 쓰기 종료