[unix] 모든 파일 줄이 다른 파일에서 발생하는지 확인

나는 2 개의 파일을 가지고 있습니다 : file1은 약 10 000 줄이고 file2는 몇 백 줄입니다. file2의 모든 줄이 file1에서 발생하는지 확인하고 싶습니다. 즉 : ∀ line ℓ ∈ file2 : ℓ ∈ file1

이 기호의 의미 또는 “file2의 모든 행이 file1에서 발생하는지 확인”의 의미를 모르는 경우 다음 중 하나를 의미합니다. 두 파일 중 하나의 동등한 행은 파일이 요구 사항을 충족하는지 여부를 확인하는 데 영향을 미치지 않습니다.

어떻게해야합니까?



답변

comm -13 <(sort -u file_1) <(sort -u file_2)

이 명령은 고유 한 행을 출력합니다 file_2. 따라서 출력이 비어 있으면 모든 file_2줄이에 포함됩니다 file_1.

통신의 남자에서 :

   With  no  options,  produce  three-column  output.  Column one contains
   lines unique to FILE1, column two contains lines unique to  FILE2,  and
   column three contains lines common to both files.

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

답변

[ $(grep -cxFf file2 <(sort -u file1)) = $(sort -u file2 | wc -l) ] &&
  echo all there ||
  echo some missing

file1 (file의 고유 행)에서 일치하는 파일 수가 file2의 고유 행 수와 일치하면 모두 존재합니다. 그렇지 않으면 그렇지 않습니다.


답변

GNU awk가 특정 length(array)기능 (및 awk지원할 수있는 다른 구현)을 지원하고 파일을 정렬 할 경우 필요하지 않은 곳에서 사용합니다.

gawk 'FNR==NR{seen[$0];next} ($0 in seen){delete seen[$0]};
    END{print (!length(seen))?"Matched":"Not Matched"}' file2 file1

이것은 판독되는 파일 2을 라는 배열 seen의 전체 행과 키 파일 2 .

그런 다음 file1을 읽고 배열의 행과 일치하면 각 행에 대해 해당 키를 삭제하십시오.

배열이 비어 있으면 마지막에 file2의 모든 행 이 file1에 존재 하고 인쇄 Matched되고 그렇지 않으면 표시됩니다 Not Matched.


모든 awk구현 에서 호환성 .

awk 'FNR==NR{seen[$0];next} ($0 in seen){delete seen[$0]};
    END{for(x in seen);print (!x)?"Matched":"Not Matched"}' file2 file1

file2에있는 경우에만 빈 줄 또는 공백이있는 줄을 무시하려면 배열에서 읽지 않는 NF조건 을 추가해야합니다 NR==FNR && NF {....


답변

를 사용 comm하면 두 파일에서 공통 인 줄을 찾을 수 있습니다.

comm -12 file1 file2

man comm자세한 내용을 살펴보십시오


답변

diff -q <(sort -u file2) <(grep -Fxf file2 file1 | sort -u)

경우에는 출력을 생성하지 않습니다 file1포함 모든 라인file2상태와 종료 0그렇지 않으면 뭔가를 인쇄합니다,

Files /proc/self/fd/11 and /proc/self/fd/12 differ

상태로 종료 1


답변

파이썬 프로그램을 사용하십시오 :

#!/usr/bin/env python3
import sys

def open_arg(path):
    return sys.stdin if path == '-' else open(path)

def strip_linebreak(s):
    return s[:-1] if s.endswith('\n') else s

with open_arg(sys.argv[1]) as pattern_file:
    patterns = set(map(strip_linebreak, pattern_file))

with open_arg(sys.argv[2]) as dataset_file:
    for l in map(strip_linebreak, dataset_file):
        patterns.remove(l)
        if not patterns:
            break

sys.exit(int(bool(patterns)))

용법:

python3 contains-all.py file2 file1

프로그램 종료 상태는 파일 2의 모든 패턴이 일치했는지 여부를 나타냅니다.

  • 0 (성공)은 모든 패턴이 일치했음을 의미합니다.
  • 1 (실패)은 일부 패턴이 일치하지 않음을 의미합니다.

쉘 (스크립트)에서 종료 상태를 쿼리하려면 $?특수 변수 또는 명령 종료 상태를 평가하는 다른 표현식 (예 : 단락 연산자 &&및 또는 ||과 같은 조건식)을 사용할 수 있습니다. 예:ifwhile

if python3 compare-all.py file2 file1 && some-other --condition; then
    # do stuff
fi


답변

combine에서 moreutils는 당신에게 모든 라인이 표시됩니다에 file2그에없는 file1과 :

combine file2 not file1

그런 다음 다음 wc -l과 같이 배관하여 줄 수를 계산할 수 있습니다 .

if [ $(combine file2 not file1 | wc -l) != 0 ]; then
  echo "lines missing"
else
  echo "You're fine"
fi