programing

한 파일에서 다른 파일에 없는 행을 빠르게 찾을 수 있는 방법?

telecom 2023. 4. 10. 20:56
반응형

한 파일에서 다른 파일에 없는 행을 빠르게 찾을 수 있는 방법?

큰 파일(파일명 세트)이 2개 있습니다.각 파일에 약 30.000 행이 있습니다.file2에 없는 행을 file1에서 빠르게 찾을 수 있는 방법을 찾고 있습니다.

예를 들어, 이것이 file1인 경우:

line1
line2
line3

다음은 file2 입니다.

line1
line4
line5

결과/출력은 다음과 같습니다.

line2
line3

이 방법은 다음과 같습니다.

grep -v -f file2 file1

하지만 대용량 파일에 사용하면 속도가 매우 느립니다.

것 같아요.diff()다만, 출력은 회선 이며, 그 외의 것은 없습니다.스위치를 찾을 수 없는 것 같습니다.

bash 및 기본 Linux 바이너리를 사용하여 이 작업을 신속하게 수행할 수 있는 방법을 찾는 데 도움을 주실 수 있습니까?

편집: 제 질문에 대한 후속 조치를 취하기 위해, 이것이 지금까지 제가 찾은 가장 좋은 방법이라고 생각합니다.diff():

diff file2 file1 | grep '^>' | sed 's/^>\ //'

물론, 더 좋은 방법이 있겠죠?

comm 명령어('공통'의 줄임말)가 도움이 될 수 있습니다.comm - compare two sorted files line by line

#find lines only in file1
comm -23 file1 file2 

#find lines only in file2
comm -13 file1 file2 

#find lines common to both files
comm -12 file1 file2 

man이 경우 파일을 읽을 수 있습니다.

은, GNU 의 /신규 행/되지 않은 을 GNU 의 「/」/「/」/「/」로 제어함으로써 할 수 .diff★★★★

diff --new-line-format="" --unchanged-line-format=""  file1 file2

이 작업을 수행하려면 입력 파일을 정렬해야 합니다.와 함께bash (그리고)zsh) 치환을 할 수 있습니다<( ):

diff --new-line-format="" --unchanged-line-format="" <(sort file1) <(sort file2)

의 새 라인 및 변경되지 않은 라인은 억제되므로 변경된 라인(즉, 사용자의 경우 제거된 라인)만 출력됩니다.몇 개 사용할 수도 있습니다.diff되지 않는 예:-i-E,-b,-v(으)ㄹㄹㄹㄹㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴ)


설명.

' '--new-line-format,--old-line-format ★★★★★★★★★★★★★★★★★」--unchanged-line-format을 할 수 있도록 diff.printf포맷 지정자.이러한 옵션은 각각 신규(추가) , 오래된(삭제) 및 변경되지 않은 행의 형식을 지정합니다.1 을 empty " 로 설정하면, 그러한 종류의 행이 출력되지 않게 됩니다.

Unified diff 포맷에 익숙한 경우 다음을 사용하여 부분적으로 다시 작성할 수 있습니다.

diff --old-line-format="-%L" --unchanged-line-format=" %L" \
     --new-line-format="+%L" file1 file2

%L으로, 또는 "-"를. 지정자처럼 "+"는 "-"는 "-"는 "-"는 "-"는 "-"는 "-"는 "-"는 "-는"로 붙습니다.diff -u되므로 (「」, 「」는 됩니다).--- +++ ★★★★★★★★★★★★★★★★★」@@각 그룹화된 변경사항의 맨 위에 있는 줄)에 번호를 매기는다른 유용한 작업에도 사용할 수 있습니다.%dn.


diff)comm ★★★★★★★★★★★★★★★★★」join)는 정렬된 입력으로 예상되는 출력만 생성합니다.단,<(sort ...)정렬할 수 있습니다.간단한 .awk(nawk) 스크립트(Konsolebox의 응답에 링크된 스크립트에서 영감을 받아)는 임의로 정렬된 입력 파일을 받아 file1에서 발생한 순서대로 누락된 행을 출력합니다.

# output lines in file1 that are not in file2
BEGIN { FS="" }                         # preserve whitespace
(NR==FNR) { ll1[FNR]=$0; nl1=FNR; }     # file1, index by lineno
(NR!=FNR) { ss2[$0]++; }                # file2, index by string
END {
    for (ll=1; ll<=nl1; ll++) if (!(ll1[ll] in ss2)) print ll1[ll]
}

의 모든 array file1에 한 합니다.ll1[]의 모든 된 어소시에이션 배열 file2의 색인화된 에 포함되어 ss2[]읽으면 다시 ll1를 사용합니다.infile1 file2 file2 (이것에 의해, ()diff★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★♪

파일이 너무 커서 둘 다 저장하면 메모리 문제가 발생할 경우 file1만 저장하고 file2를 읽을 때 일치하는 파일을 삭제함으로써 CPU와 메모리를 교환할 수 있습니다.

BEGIN { FS="" }
(NR==FNR) {  # file1, index by lineno and string
  ll1[FNR]=$0; ss1[$0]=FNR; nl1=FNR;
}
(NR!=FNR) {  # file2
  if ($0 in ss1) { delete ll1[ss1[$0]]; delete ss1[$0]; }
}
END {
  for (ll=1; ll<=nl1; ll++) if (ll in ll1) print ll1[ll]
}

배열에 는 행 file1로 색인화되어 .이치노ll1[]의 내용에 , 1개입니다.ss1[]하는 각 이 file2에서 ll1[] ★★★★★★★★★★★★★★★★★」ss1[]되어 원래의 마지막에 file1의 나머지 행이 출력되어 원래의 순서가 유지됩니다.

이 경우, 전술한 문제에서는 GNU를 사용하여 분할정복할 수도 있습니다.split입니다), 되어 file2를 읽습니다

split -l 20000 --filter='gawk -f linesnotin.awk - file2' < file1

「 」의 및 에 주의해 .-stdin gawk것, ,, by, by, 에, 에에서 제공하는 것입니다.split「20000」 「file1」 「file1」 「file1」 「file1」.

GNU가 아닌 시스템의 사용자에게는 GNU를 제공하는 Apple Xcode 툴의 일부로서 OSX를 포함한 GNU coreutils 패키지를 얻을 수 있습니다.diff,awk POSIX ,, POSIX/BSD 입 a a 。splitGNU 버 gnu gnu gnu

Konsolebox가 제안하는 것처럼 포스터 GREP 솔루션

grep -v -f file2 file1

'아까운'을 더하면 -Foption:을 정규 합니다.option: 「정규 표현이 아닌 「고정 문자열로 취급합니다.비교해야 할 1000행까지의 파일목록에서 확인했습니다.★★★★★★★★★★★★★★★★ -F을 GREP 「」로 했을 때는, 0.초(가 걸렸지만, 는 2초(가 걸렸어요.wc -l.

에는 「이러한 테스트」도되어 있습니다.-x스위치: file2에 file1 내의 1개 이상의 행이 모두 일치하는 것은 아니지만 일부 행이 포함되어 있는 경우 완전한 정확성을 확보하기 위해 솔루션의 일부입니다.

따라서 입력을 정렬할 필요가 없고, 빠르고, 유연한 솔루션(대문자와 소문자의 구별 등)은 다음과 같습니다.

grep -F -x -v -f file2 file1

예를 들어 macOS에서는 파일1의 행이 하위 문자열인 다른 행과 일치하더라도 파일1의 행이 파일2에 존재하지 않는 것으로 표시되는 등 모든 버전의 grep에서는 동작하지 않습니다.또는 이 솔루션을 사용하기 위해 MacOS에 GNU grep를 설치할 수도 있습니다.

들어 tool"이 "Linux"만 있는 이 .cat,sort ★★★★★★★★★★★★★★★★★」uniq:

cat includes.txt excludes.txt excludes.txt | sort | uniq --unique

테스트:

seq 1 1 7 | sort --random-sort > includes.txt
seq 3 1 9 | sort --random-sort > excludes.txt
cat includes.txt excludes.txt excludes.txt | sort | uniq --unique

# Output:
1
2    

, 이 동작은,grep.

종류와 차이는 얼마나 빠른가?

sort file1 -u > file1.sorted
sort file2 -u > file2.sorted
diff file1.sorted file2.sorted

combine부에서moreutils package, a sets utility that supports 패키지, 를 지원하는 유틸리티 세트not,and,or,xor운영 작

combine file1 not file2

즉, file1에는 있지만 file2에는 없는 행을 지정합니다.

또는 file1에서 file2에서 행을 뺀 행을 지정합니다.

참고: 감사합니다. combine어떤 작업을 수행하기 전에 파일에서 고유한 선을 찾습니다. 수 행 일 유 을 렬 정 검 다 합 색 니 sorts but operation files beforeing perform lines행고하고한 anydiff하지 않다.지 다 그래서 문 에 때 of 력 이 는 우 있 습 니다 so경있가차 find might않 output you출rences가이에, between diffe의하diff ★★★★★★★★★★★★★★★★★」combine

그래서 사실상 당신은 말하고 있다.

file1과 file2에서 다른 행을 찾은 후 file1에서 file2에서 행을 뺀 행을 지정합니다.

제 경험상 다른 옵션보다 훨씬 빠릅니다.

이건 빠른 것 같아요.

comm -1 -3 <(sort file1.txt) <(sort file2.txt) > output.txt
$ join -v 1 -t '' file1 file2
line2
line3

-t라인에 우주선을 비교한다면 모든 선을 비교하면 됩니다.일부 행에 공백이 있는 경우 행 전체를 비교합니다.

Python을 사용할 수 있습니다.

python -c '
lines_to_remove = set()
with open("file2", "r") as f:
    for line in f.readlines():
        lines_to_remove.add(line.strip())

with open("f1", "r") as f:
    for line in f.readlines():
        if line.strip() not in lines_to_remove:
            print(line.strip())
'

fgrep을 사용하거나 grep에 -F 옵션을 추가하면 도움이 됩니다.하지만 더 빠른 계산을 위해서는 Awk를 사용할 수 있습니다.

다음 중 하나의 방법을 사용해 볼 수 있습니다.

http://www.linuxquestions.org/questions/programming-9/grep-for-huge-files-826030/ #post4066219

은 '아까운'을 입니다.--suppress-common-lines단, 이 플래그는 병렬 형식으로 실행하는 경우에만 작동합니다.

diff -y --suppress-common-lines file1.txt file2.txt

언급URL : https://stackoverflow.com/questions/18204904/fast-way-of-finding-lines-in-one-file-that-are-not-in-another

반응형

'programing' 카테고리의 다른 글

SQL Server에서 하위 쿼리를 사용하여 쿼리 업데이트  (0) 2023.04.10
vs  (0) 2023.04.10
로컬 스토리지와 쿠키  (0) 2023.04.10
문자열이 숫자인지 식별  (0) 2023.04.10
Powershell v3 Invoke-WebRequest HTTPS 오류  (0) 2023.04.10