모든 패턴이 파일에 있는지 확인

모든 패턴이 파일에 있는지 확인

patterns.txt내가 하나 있고 이러한 패턴이 각각 특정 파일에 존재하는지 확인하고 싶다고 가정해 보겠습니다 .

다음과 같이 할 수 있습니다.

for pattern in $(cat patterns.txt); do 
  if ! grep -q "$pattern" file.txt; then
    echo "Error: missing pattern $pattern"
  fi
done
echo "All patterns found"

그러나 이는 file.txt각 패턴을 다시 검색해야 하기 때문에 비효율적입니다. 잠재적으로 큰 파이프의 스트림에 있는 파일에서 패턴을 찾지 않았다면 상황이 그렇게 간단하지 않을 것입니다.

grep확인하는 방법(또는 다른 도구)이 있습니까 ?모두패턴이 존재하는가?

답변1

cat file.txt | awk '
    NR == FNR {seen[$0] = 0; next} 
    {for (p in seen) if ($0 ~ p) seen[p]++} 
    END {
        for (p in seen) 
            if (seen[p] == 0) {
                missing++
                print "missing pattern", p
            } 
        if (missing == 0) print "all found"
        exit missing
    }
' patterns.txt -

command를 cat텍스트를 생성하는 파이프로 바꾸십시오.

답변2

이것은 잘 작동할 수 있습니다:

sort -u patterns.txt > sorted_patterns.txt # only once
diff -sq <(grep -o -f sorted_patterns.txt file.txt | sort -u) sorted_patterns.txt

패턴 대신 고정 문자열이 있는 경우 이것을 사용 하면 훨씬 더 빨라 -F집니다 !grep

당신은 할 수또한 사용cmp바꾸다 diff -s. 조금 더 빠를 수도 있지만 누락된 내용은 표시되지 않습니다.


모든 패턴이 발견되지 않은 경우 다음을 출력합니다.

Files /dev/fd/63 and /dev/fd/62 differ

또는 모든 패턴이 발견된 경우:

Files /dev/fd/63 and /dev/fd/62 are identical

떠나기 -q전까지는 알 수 없을 거야무엇다 쓴.

2a3
> missing_word

답변3

grepPCRE 확장을 사용 하고 printf명령의 기능을 사용하면 다음과 같은 작업을 수행할 수 있습니다.

<infile grep -qzP "(?s)$(printf "(?=.*?%s)" $(<pattern.txt))" &&
 echo 'all matched' ||
 echo 'one or more pattern(s) does not found'

모든 모드(in어떤 주문이든)가 입력 파일에 있습니다.네펠레그런 다음 문자 메시지를 보내all matched그렇지 않으면 텍스트로 출력됩니다.one or more pattern(s) does not found에코됩니다.

이는 패턴을 일치 패턴으로 사용합니다. 예를 들어 정확한 패턴과 일치하기 위해 & 와 pat[01]일치하고 문자 그대로 특수 문자를 이스케이프하도록 제어 수정자를 변경합니다 .pat0pat1pat[01]printf%s%q

<infile grep -qzP "(?s)$(printf "(?=.*?%q)" $(<pattern.txt))" &&
 echo 'all matched' ||
 echo 'one or more pattern(s) does not found'

관련 정보