![특정 텍스트가 발견되면 태그 사이에 텍스트를 인쇄합니다(포함).](https://linux55.com/image/37008/%ED%8A%B9%EC%A0%95%20%ED%85%8D%EC%8A%A4%ED%8A%B8%EA%B0%80%20%EB%B0%9C%EA%B2%AC%EB%90%98%EB%A9%B4%20%ED%83%9C%EA%B7%B8%20%EC%82%AC%EC%9D%B4%EC%97%90%20%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%A5%BC%20%EC%9D%B8%EC%87%84%ED%95%A9%EB%8B%88%EB%8B%A4(%ED%8F%AC%ED%95%A8)..png)
내 임무는 여러 Apache 서버에서 데이터를 추출하는 것입니다. 작업은 다음을 인쇄하는 것입니다.
<Directory ...>
...
</Directory>
+ExecCGI가 있는 곳입니다. 설명하기 위해 예를 들어 보겠습니다. Apache 구성 파일에 다음과 같은 많은 디렉터리 섹션이 있다고 가정합니다.
<Directory /var/www/site1/htdocs>
Options +ExecCGI
...
...
</Directory>
...
...
...
<Directory /var/www/site1/Promo>
Options -ExecCGI
...
...
</Directory>
위에서 다음과 같은 출력을 원합니다.
<Directory /var/www/site1/htdocs>
Options +ExecCGI
...
...
</Directory>
포럼을 검색한 결과 사람들이 라벨 사이에 전체 섹션을 인쇄하는 방법(저도 그 방법을 알고 있습니다)이나 발견 시 일부 텍스트를 변경하는 방법(이 시점에서도 어떻게 하는지 알고 있습니다)에 대해 질문하는 게시물을 찾았습니다. .
+ExecCGI를 -ExecCGI로 변경하겠습니다. 하지만 변경 사항은 검토 과정을 거쳐야 하므로 이 질문을 통해 이 데이터를 추출할 수 있습니다.
답변1
perl -l -0777 -ne 'for (m{<Directory.*?</Directory>}gs) {print if /\+ExecCGI/}'
또는 GNU를 사용하십시오 grep
:
grep -zPo '(?s)<Directory(?:.(?!</Directory))*?\+ExecCGI.*?</Directory>'
답변2
당신은 또한 사용할 수 있습니다awk
awk 'BEGIN{RS="</Directory>\n"; ORS=RS} /\+ExecCGI/ {print}' file
답변3
사용할 수 있는 경우 perl
해결책은 다음과 같습니다 .
$ perl -nle '
if (/<Directory/) {
$flag = 1;
}
push @a, $_ if $flag;
if (/<\/Directory/) {
$flag = 0;
if (grep {$_ =~ /\+ExecCGI/} @a) {
push @f, @a;
}
@a = ();
}
END {
print join "\n", @f;
}' file
<Directory /var/www/site1/htdocs>
Options +ExecCGI
...
...
</Directory>
설명하다
- 우리는 그것을 볼 때마다
<Directory
그것을 설정합니다$flag = 1
. - true(1은 부울 컨텍스트에서 true를 의미) 인 경우
$flag
현재 항목을 배열에 푸시합니다@a
. - 가 보이면
</Directory
블록 작업이 완료되었음을 의미하며 블록에+ExecCGI
문자열이 포함되어 있는지 확인한grep {$_ =~ /\+ExecCGI/
다음 푸시@a
합니다@f
. @a
다른 블록을 처리하려면 빈 배열로 설정하세요 .
답변4
다음은 Bash의 예입니다(거의 모든 언어에서 비슷한 작업을 수행할 수 있어야 합니다).
$ cat test.sh
#!/bin/bash
DIR=0
BLOCK=''
while read line
do
if [ $DIR -eq 0 ] ; then
if [[ $(echo $line | grep -i '<Directory') ]] ; then
DIR=1
BLOCK="$line"
fi
else
BLOCK="$BLOCK\n$line"
if [[ $(echo $line | grep -i '</Directory') ]] ; then
if [[ $(echo $BLOCK | grep -i 'Options.*+ExecCGI') ]] ; then
echo -e $BLOCK
fi
DIR=0
BLOCK=""
fi
fi
done
기본적으로 우리는 블록을 저장하면서 grepping
패턴이 포함되어 있는지 확인합니다.
이는 매우 간단하며 일부 극단적인 경우에 문제를 일으킬 수 있지만( echo -e
예를 들어 구성 파일에 \가 있으면 혼란스러울 수 있음) 이를 처리하기 위해 기본 아이디어를 확장할 수 있습니다.
사용 예:
$ cat test.conf
<Directory /var/www/site1/htdocs>
Options +ExecCGI
1
2
</Directory>
3
4
5
<Directory /var/www/site1/Promo>
Options -ExecCGI
6
7
</Directory>
<Directory /var/www/site1/htdocs>
Options -Whatever +ExecCGI
8
9
</Directory>
$ cat test.conf | bash test.sh
<Directory /var/www/site1/htdocs>
Options +ExecCGI
1
2
</Directory>
<Directory /var/www/site1/htdocs>
Options -Whatever +ExecCGI
8
9
</Directory>