awk 또는 sed 명령은 특정 줄의 정규식과 일치하고 성공하면 true를 종료하고, 그렇지 않으면 false를 종료합니다.

awk 또는 sed 명령은 특정 줄의 정규식과 일치하고 성공하면 true를 종료하고, 그렇지 않으면 false를 종료합니다.

파일에 다음이 포함되어 있는지 확인해야 합니다.특정 줄에 대한 특정 정규식발견되면 true(0 종료)를 반환하고, 그렇지 않으면 false를 반환합니다. 내가 너무 생각하고 있었을지도 모르지만, 내 시도는 조금 서투른 것으로 판명되었습니다. 해결책이 있는데 생각하지 못한 다른 해결책을 찾고 있습니다. Perl을 사용할 수도 있지만 꼭두각시 실행 주기 내에서 실행되므로 이를 가능한 한 "경량"으로 유지하고 싶습니다.

이 문제는 일반적입니다. RHEL6에서는 132에서 줄의 주석 처리를 해제하지 않는 한 터미널 너비를 80자로 제한하는 방식으로 화면이 패키지됩니다. 이 명령은 해당 줄이 수정되었는지 확인합니다.

 awk 'NR==132 && /^#termcapinfo[[:space:]]*xterm Z0=/ {x=1;nextfile} END {exit 1-x}' /etc/screenrc

참고: 파일이 132줄 미만인 경우 false로 종료해야 합니다.

여기서는 도움이 될 것이라고 생각 sed하지만 분명히 널 대체 및 분기와 같은 이상한 트릭을 수행해야 합니다. 그래도 배울 수 있는 sed 솔루션을 보고 싶습니다. 어쩌면 내가 간과하고 있는 다른 것들이 있을 수도 있습니다.

편집 1: nextfile내 awk 솔루션에 추가됨

편집 2: 기준 편집 3: 다른 호스트(유휴). 편집 4: 각 실행을 최적화하기 위해 Gile의 awk 시간을 잘못 사용했습니다. 편집 5: 새로운 벤치

벤치마크

먼저 참고 사항: wc -l /etc/screenrc216. 라인이 존재하지 않는 경우 50,000회 반복(벽 시간으로 측정):

  • 무작동: 0.545초
  • 내 원래 awk 솔루션: 58.417
  • 내 편집된 awk 솔루션(nextfile 사용): 58.364s
  • Giles의 awk 솔루션: 57.578s
  • 최적화된 Perl 솔루션 90.352s 아야!
  • Sed 132{p;q}|grep -q ...솔루션: 61.259초
  • Cuonglm의 tail | head | grep -q: 70.418s 아야!
  • Don_Christie's head -nX |head -n1|grep -q: 116.9s 우후!
  • Terdon의 이중 grep 솔루션: 65.127s
  • John1024의 sed 솔루션:45.764초

고마워요 존, 고마워요 sed! 솔직히 말해서 Perl이 여기에 동급이라는 사실에 놀랐습니다. Perl은 시작 시 여러 공유 라이브러리를 로드하지만 운영 체제가 모든 라이브러리를 캐시하는 한 이는 파서 및 바이트 인코더에 따라 달라집니다. 먼 과거(perl 5.2?)에는 20% 더 느린 것으로 나타났습니다. 처음에 예상했던 대로 Perl은 느리지만 복사/붙여넣기 오류로 인해 Perl이 더 나은 것 같습니다.

벤치마킹 2부

실용적인 가치가 있는 가장 큰 구성 파일은 입니다 /etc/services. 그래서 이 파일에 대한 벤치를 다시 실행했는데 변경할 줄은 파일 전체의 2/3였습니다. 총 행 수는 1100이었으므로 7220을 선택하고 그에 따라 정규 표현식을 수정했습니다(한 경우에는 실패하고 다른 경우에는 성공하도록, 워크벤치의 경우 항상 실패함).

  • John의 sed 솔루션: 121.4s
  • Christie의 {head;head}|grep솔루션: 138.341s
  • Kangam의 tail|head|grep솔루션:77.948초
  • 내 awk 솔루션: 175.5s

답변1

GNU sed 사용:

sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q}; $q1'

어떻게 작동하나요?

  • 132 {/^#termcapinfo[[:space:]]*xterm Z0=/q}

    132행에서 정규식을 확인합니다 ^#termcapinfo[[:space:]]*xterm Z0=. 종료가 발견되면 q기본 종료 코드는 0입니다. 파일의 나머지 부분은 건너뜁니다.

  • $q1

    마지막 줄에 도달하면 $종료 코드 1: 을 사용하여 종료합니다 q1.

능률

파일의 132번째 줄을 읽을 필요가 없기 때문에 이 버전은 132번째 줄이나 파일의 끝에 도달하는 중 먼저 발생하는 즉시 종료됩니다.

sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q; q1}; $q1'

빈 파일 처리

위 버전은 빈 파일에 대해 true를 반환합니다. 파일이 비어 있으면 명령이 실행되지 않고 sed가 기본 종료 코드 0으로 종료되기 때문입니다. 이러한 상황을 방지하려면 다음을 수행하세요.

! sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q1; q}'

여기서 sed 명령은 필요한 문자열이 발견되지 않는 한 코드 0으로 종료되고, 해당 문자열이 발견되면 코드 1로 종료됩니다. 앞의 !내용은 쉘에게 이 코드를 뒤집어 우리가 원하는 코드로 돌아가도록 지시합니다. !모든 POSIX 쉘은 이 수정자를 지원합니다. 이 버전은 빈 파일에서도 작동합니다. (모자팁: G-Man)

답변2

POSIX 도구 상자 사용:

tail -n +132 </etc/screenrc | head -n 1 | grep -q pattern

답변3

awk에서 이 작업을 더 효율적으로 수행할 수 있습니다. 관련 줄에 도달하면 종료하세요.

awk 'NR==132 {if (/^#termcapinfo[[:space:]]*xterm Z0=/) found=1; exit}
     END {exit !found}' /etc/screenrc

아니면 할 수 있습니다GNU sed 사용(그러나 휴대용 sed에서는 종료 코드를 지정할 수 없습니다.)

또는 도구를 함께 그룹화하는 Unix 철학을 사용할 수 있습니다. 즉, head원하는 줄을 사용 및 추출 tail하고 에 전달합니다 grep.

</etc/screenrc tail -n +132 | head -n 1 |
grep -q '^#termcapinfo[[:space:]]*xterm Z0='

또는 sed를 사용하여 필요한 줄을 추출할 수 있습니다.

</etc/screenrc sed -n '32 {p; q;}' |
grep -q '^#termcapinfo[[:space:]]*xterm Z0='

(이 두 가지 모두 빈 줄과 너무 짧은 파일로 동일한 결과를 원한다는 사실에 의존합니다.)

head이러한 작은 파일의 경우 가장 빠른 방법은 단일 도구를 사용하는 것입니다. 여러 프로그램을 실행하는 오버헤드가 전용 도구(예 : , 및 )를 사용하여 tail얻을 수 있는 성능 향상 보다 크기 때문입니다 sed. 행 132000000을 원한다면 그것으로 시작하는 것이 tail -n +132000000아마도 다른 것보다 빠를 것입니다.

답변4

.perl

다음을 수행할 수 있습니다.

#!/usr/bin/env perl

use strict;
use warnings;

open ( my $input_fh, '<', "/etc/screenrc" ) or die $!; 
while ( <$input_fh> ) {
   if ( $. == 132 
   and m/^#termcapinfo[[:space:]]*xterm Z0=/ ) {
       exit 0; 
   }
}

exit 1;

라이너로 압축할 수 있습니다.

perl -ne 'exit 0 if $. == 132 and  m/^#termcapinfo[[:space:]]*xterm Z0=/ END { exit 1 }' 

관련 정보