그래서 끝에 단어가 있는 일련의 숫자가 포함된 텍스트 파일이 있습니다.
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
.-n
Perl이 다음과 같이 실행되도록 합니다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