grep을 사용하여 특정 문자가 X번 포함된 문자열을 포함하는 모든 줄을 찾습니다.

grep을 사용하여 특정 문자가 X번 포함된 문자열을 포함하는 모든 줄을 찾습니다.

그래서 끝에 단어가 있는 일련의 숫자가 포함된 텍스트 파일이 있습니다.

123456 126 2 12456 1256 4 46 12346 123456 4 56 word
24 245 1234 356 12346 6 3 346 245 5 12346 12356 word

8개 이상의 문자열(1개, 6개 또는 둘 다를 포함)이 있는 모든 행을 찾고 싶습니다. 따라서 첫 번째 줄에는 1, 6 또는 둘 다를 포함하는 8개의 문자열(공백으로 구분)이 있으므로 통과됩니다. 두 번째에는 1이나 6 또는 둘 다를 포함하는 7개의 문자열만 있습니다.

다음 정규식을 시도했지만 역추적 제한 오류가 발생합니다.([0-9]*(1|6)[0-9]* .*){8,}

답변1

1정규식을 작성하는 대신 아래 코드는 마지막 필드를 제외하고 공백으로 구분된 모든 필드를 반복하여 또는 가 포함된 경우 카운터를 증가시킵니다 6. 카운터 값이 8 이상이면 현재 레코드가 출력됩니다.

awk '{ count = 0; for (i = 1; i < NF; ++i) count += ($i ~ "[16]") }; count >= 8' file

다음 코드는 동일한 작업을 수행하지만 레코드를 출력하려는 ​​경우 계산을 중지합니다.

awk '{ count = 0; for (i = 1; i < NF && count < 8; ++i) count += ($i ~ "[16]") }; count == 8' file

더 짧은(읽을 수 없는) 줄로(카운터가 실행 중입니다.아래에8)부터:

awk '{c=8;for(i=1;i<NF&&c;++i)c-=$i~"[16]"}!c' file

답변2

펄 사용:

$ perl -ane 'print if (grep /[16]/, @F) >= 8' file.txt 
123456 126 2 12456 1256 4 46 12346 123456 4 56 word
  • -a각 입력 라인을 배열로 자동 분할합니다 @F.

  • -nPerl이 다음과 같이 실행되도록 합니다 sed -n(즉, 각 입력 줄을 반복하되 명시적으로 지시하지 않는 한 아무것도 인쇄하지 않음).

  • -e다음 매개변수는 실행할 스크립트입니다.

  • 스칼라 컨텍스트에서 사용될 때 perl grep()함수는 일치 항목 수를 반환합니다(반면 목록 컨텍스트에서는 일치 항목 목록을 반환합니다). 즉, 배열에서 일치하는 요소의 수를 계산합니다 @F.

    이 기능은 다음과 유사합니다.아니 똑같다명령 grep줄 프로그램. perldoc -f grep자세히보다.


그런데 일치하는 항목 수도 인쇄하려면 다음과 같이 할 수 있습니다.

$ perl -ane '$x = grep /[16]/, @F; if ($x >= 8) {printf "%2i: %s", $x, $_}' /tmp/junk.txt 
 8: 123456 126 2 12456 1256 4 46 12346 123456 4 56 word

답변3

사용sed

$ sed -En 's/ ?[0-9]*[16][0-9]* /&/p8' input_file
123456 126 2 12456 1256 4 46 12346 123456 4 56 word

관련 정보