일치하는 줄이 없는 입력 패턴을 인쇄하는 방법은 무엇입니까?

일치하는 줄이 없는 입력 패턴을 인쇄하는 방법은 무엇입니까?

패턴이 일치하는 파일을 찾으려면 이 grep 명령이 있습니다.

grep -oiE 'pattern1|pattern2|pattern3|pattern4' *pattern_in_a_filename* | sort -u

산출:

file_one:pattern1
file_two:pattern2
file_two:pattern3

내가 원하는 것은 pattern4다음 예와 같이 찾을 수 없음 문을 출력하는 것입니다.

file_one:pattern1
file_two:pattern2
file_two:pattern3
pattern4 not found

저는 수천 개의 패턴을 만들고 있는데 이는 우리 작업에 필요한 중요한 데이터이기 때문에 신속하게 완료해야 합니다.

답변1

이렇게 해야 해빠른가능한 한 많이

일을 빨리 끝내고 싶나요?

발견하다병렬 처리다음 GNU를 적용하십시오parallel해결책:

올바른 방법은 모든 패턴을 파일(예: patterns.txt.

주요 업무:

cat patterns.txt | parallel -j 0 --no-notice 'grep -Hoi {} /path/to/files/* || echo "{} not found"' | sort -u
  • -j N- 직위 수. N작업을 병렬로 실행합니다 . 0최대한 의미를 부여합니다. 기본값은 100%이며, 이는 CPU 코어당 하나의 작업을 의미합니다.

위의 명령은 모든 항목을 검색합니다.무늬patterns.txt모든 파일 에서 병렬.

테스트를 해보니 그냥2CPU 코어에는 일부 패턴 목록과 각각 641Mb의 일부 csv 파일이 포함되어 있습니다. 나는 약을 가지고 있습니다.470%연속 처리에 비해 시간 속도가 향상됩니다.
컴퓨터에 CPU 코어가 많을수록 더 빠른 성능을 얻을 수 있습니다.

결론을 내리세요...

https://www.gnu.org/software/parallel/man.html

답변2

이 도구는 grep패턴별로 파일을 검색합니다. 이는 패턴이 입력이고 파일이 출력임을 의미합니다. 즉, grep으로 찾을 수 있는 것은 패턴이 아니라 파일뿐이라는 의미입니다.

일치하는 패턴이 포함되지 않은 파일을 찾으려면 를 사용해야 합니다 -v. 이를 위해서는 두 번의 호출이 필요합니다.

예:

$ echo a > xa
$ echo ab > xab
$ echo c > xc
$ { grep -oiE 'a|b' x*; grep -vl -E 'a|b' x*; } | sort -u
xa:a
xab:a
xab:b
xc

일치하지 않는 패턴을 찾으려면 패턴을 입력으로 제공하고 검색 결과를 패턴으로 제공해야 합니다. 일치 항목 목록은 패턴이 되고, 패턴은 검색해야 하는 데이터가 됩니다.

이것이 이전 예제의 파일 패턴일 수 있다고 가정합니다.

$ pattern='a|b|d'

그런 다음 일치하는 패턴 목록을 배열에 저장합니다.

$ found=($(grep -hoiE "$pattern" x* | sort -u))

그러면 배열이 새 모드로 변환됩니다.

$ new_pattern="$(IFS='|' ; echo "${found[*]}")"

그러면 원시 스키마가 데이터로 변환됩니다.

$ data="${pattern//|/$'\n'}"

일치하지 않는 패턴 목록은 다음과 같습니다.

$ grep -viE "$new_pattern" <<< "$data"
d

답변3

기대치를 달성하는 방법은 다음과 같습니다. 수천 개의 패턴이 있다고 하셨으니,무늬파일에서 직접 전달하는 것보다 훨씬 낫습니다.무늬도착하다 grep. 명령은 다음과 같습니다.

grep -oif ../patt_file file* && 
    printf "%s Not Found.\n" $(grep -vFxf <(grep -oihf ../patt_file file*) \
    <(< ../patt_file))

일치하지 않으려면무늬파일 자체는 입력이 있는 디렉터리가 아닌 다른 디렉터리 patt_file로 이동해야 합니다 .infiles*

답변4

sh다음은 필요한 결과를 생성하는 스크립트 입니다 .

#!/bin/sh

grep -f /path/to/patterns.txt /path/to/*_856_2017* | sort -u > /path/to/foundFiles.txt 

while read -r LINE
do
    grep -F "$LINE" /path/to/foundFiles.txt
    if [ $? -eq 1 ]
    then
        echo "$LINE" not found
    fi
done < /path/to/patterns.txt

이 스크립트에서는 귀하의 출력이당신의 grep파일에 저장 found.txt하고 패턴을 파일에 저장합니다 /path/to/foundFiles.txt.

보시다시피 in 루프는 누락된 내용을 추가하면서 grep파일의 동일한 내용을 생성합니다 .found.txt"$pattern" not found

또한 귀하의 경우에 대한 두 번째 접근 방식을 고안했습니다.

#!/bin/sh

grep -f /path/to/patterns.txt /path/to/*_856_2017* |
    sort -u > /path/to/foundFiles.txt

comm -23 /path/to/patterns.txt /path/to/foundFiles.txt |
    xargs -L 1 -I {} echo {} not found > /path/to/notFoundFiles.txt

cat /path/to/foundFiles.txt /path/to/notFoundFiles.txt > /path/to/finalList.txt

이 경우 이것이 작동 patterns.txt하려면 이미 정렬되어 있어야 합니다 .comm

이 명령은 두 파일을 비교하고 찾을 수 없는 패턴 목록인 ( 인수) comm에 나타나는 행만 반환합니다 .patterns.txt-23grep

그런 다음 xargs각 줄( -L 1) 을 잡고 {}"찾을 수 없음"이 추가된 해당 줄( )을 에코합니다. 결과는 파일 xargs로 리디렉션됩니다 .notFoundFiles.txt

마지막으로 findFiles.txt와 notFoundFiles.txt를 finalList.txt.

관련 정보