태그 보관물: vimdiff

vimdiff

텍스트 파일이 다른 파일의 하위 집합인지 확인하는 방법 교차 점검이어야하며 다음을 반환해야합니다. file1 subset of

텍스트 파일이 다른 파일의 하위 집합인지 확인하는 방법을 찾으려고합니다.

예를 들면 다음과 같습니다.

foo
bar

의 하위 집합입니다

foo
bar
pluto

동안:

foo
pluto

foo
bar

서로의 하위 집합이 아닙니다 …

명령으로 이것을 수행하는 방법이 있습니까?

이 점검은 반드시 교차 점검이어야하며 다음을 반환해야합니다.

file1 subset of file2 :    True
file2 subset of file1 :    True
otherwise             :    False



답변

그 파일의 내용이 호출하는 경우 file1, file2그리고 file3apearance의 순서로 당신은 다음과 같은 한 줄에 그것을 할 수 있습니다 :

 # python -c "x=open('file1').read(); y=open('file2').read(); print x in y or y in x"
 True
 # python -c "x=open('file2').read(); y=open('file1').read(); print x in y or y in x"
 True
 # python -c "x=open('file1').read(); y=open('file3').read(); print x in y or y in x"
 False


답변

perl:

if perl -0777 -e '$n = <>; $h = <>; exit(index($h,$n)<0)' needle.txt haystack.txt
then echo needle.txt is found in haystack.txt
fi

-0octal레코드 분리 문자를 정의합니다. 8 진수가 0377 (최대 바이트 값)보다 크면 분리 문자가 없음을 의미하며 이는 것과 같습니다 $/ = undef. 이 경우 <>단일 파일의 전체 내용을 반환 합니다 . 이것이 slurp 모드 입니다.

우리는 두 가지의 파일의 내용을 일단 $h$n변수를 우리가 사용할 수있는 index()하나가 다른에서 찾을 수 있는지 확인.

그러나 전체 파일이 메모리에 저장되어 있기 때문에 매우 큰 파일에는 방법이 작동하지 않습니다.

mmappable 파일 (일반적으로 일반 파일 및 블록 장치와 같이 검색 가능한 대부분의 파일 포함)의 mmap()경우 Sys::Mmapperl 모듈 과 같이 파일 을 사용하여 해결할 수 있습니다 .

if
  perl -MSys::Mmap -le '
    open N, "<", $ARGV[0] || die "$ARGV[0]: $!";
    open H, "<", $ARGV[1] || die "$ARGV[1]: $!";
    mmap($n, 0, PROT_READ, MAP_SHARED, N);
    mmap($h, 0, PROT_READ, MAP_SHARED, H);
    exit (index($h, $n) < 0)' needle.txt haystack.txt
then
  echo needle.txt is found in haystack.txt
fi


답변

이 질문 덕분에 해결책을 찾았습니다.

기본적으로 나는 두 개의 파일 테스트입니다 a.txtb.txt이 스크립트 :

#!/bin/bash

first_cmp=$(diff --unchanged-line-format= --old-line-format= --new-line-format='%L' "$1" "$2" | wc -l)
second_cmp=$(diff --unchanged-line-format= --old-line-format= --new-line-format='%L' "$2" "$1" | wc -l)

if [ "$first_cmp" -eq "0" -o "$second_cmp" -eq "0" ]
then
    echo "Subset"
    exit 0
else
    echo "Not subset"
    exit 1
fi

하나가 다른 것의 부분 집합이면 스크립트 0True그렇지 않으면를 반환 합니다 1.


답변

f1이 f2의 부분 집합 인 경우 f1-f2는 빈 세트입니다. 이를 바탕으로 is_subset 함수와 그 함수를 작성할 수 있습니다. 두 개의 텍스트 파일 간의 설정 차이에 따라

sort_files () {
  f1_sorted = "$ 1.sorted"
  f2_sorted = "$ 2.sorted"

  만약 [ ! -f $ f1_sorted]; 그때
    고양이 $ 1 | 정렬 | 유니크> $ f1_sorted
  fi

  만약 [ ! -f $ f2_sorted]; 그때
    고양이 $ 2 | 정렬 | 유니크> $ f2_sorted
  fi
}

remove_sorted_files () {
  f1_sorted = "$ 1.sorted"
  f2_sorted = "$ 2.sorted"
  rm -f $ f1_sorted
  rm -f $ f2_sorted
}

set_union () {
  sort_files $ 1 $ 2
  고양이 "$ 1.sorted" "$ 2.sorted"| 정렬 | 유니크
  remove_sorted_files $ 1 $ 2
}

set_diff () {
  sort_files $ 1 $ 2
  고양이 "$ 1.sorted" "$ 2.sorted" "$ 2.sorted"| 정렬 | 유니크 -u
  remove_sorted_files $ 1 $ 2
}

rset_diff () {
  sort_files $ 1 $ 2
  고양이 "$ 1.sorted" "$ 2.sorted" "$ 1.sorted"| 정렬 | 유니크 -u
  remove_sorted_files $ 1 $ 2
}

is_subset () {
  sort_files $ 1 $ 2
  출력 = $ (set_diff $ 1 $ 2)
  remove_sorted_files $ 1 $ 2

  만약 [-z $ output]; 그때
    0을 반환
  그밖에
    1을 반환
  fi

}


답변

에서 http://www.catonmat.net/blog/set-operations-in-unix-shell/ :

Comm은 두 개의 정렬 된 파일을 한 줄씩 비교합니다. 처음 지정된 파일에만 나타나는 행을 출력하는 방식으로 실행될 수 있습니다. 첫 번째 파일이 두 번째 파일의 하위 집합 인 경우 첫 번째 파일의 모든 줄도 두 번째 파일에 나타나므로 출력이 생성되지 않습니다.

$ comm -23 <(sort subset | uniq) <(sort set | uniq) | head -1
# comm returns no output if subset ⊆ set
# comm outputs something if subset ⊊ set

답변