programing

한 파일에서 다른 파일에 있는 줄 삭제

abcjava 2023. 4. 21. 20:06
반응형

한 파일에서 다른 파일에 있는 줄 삭제

파일이 있습니다.f1:

line1
line2
line3
line4
..
..

다른 파일에 있는 모든 행을 삭제하고 싶다.f2:

line2
line8
..
..

제가 뭘 좀 해봤는데cat그리고.sed내가 의도했던 것과는 거리가 멀었어이거 어떻게 해?

grep -v -x -f f2 f1효과가 있을 거야

설명:

  • -v비직렬선을 선택하다
  • -x행 전체를 일치시키다
  • -f f2무늬를 얻다f2

대신 사용할 수 있습니다.grep -F또는fgrep일정한 끈을 매치하다f2패턴보다 ('무엇을 얻으면 무엇을 알 수 있는가'로 선을 제거하고 싶은 경우)의 선을 처리하는 것보다f2정규식 패턴으로).

대신 comm을 시도합니다(f1과 f2가 이미 "정렬 완료"된 것으로 가정합니다).

comm -2 -3 f1 f2

크기가 너무 크지 않은 파일을 제외하려면 AWK의 관련 배열을 사용할 수 있습니다.

awk 'NR == FNR { list[tolower($0)]=1; next } { if (! list[tolower($0)]) print }' exclude-these.txt from-this.txt 

출력 순서는 "from-this.txt" 파일과 동일합니다.tolower()필요한 경우 대소문자를 구분하지 않습니다.

알고리즘의 복잡도는 아마도 O(n)(exclude-these)가 될 것입니다.txt size) + O(n)(이것부터 이것까지).txt 사이즈)

Dennis Williamson의 답변과 유사(대부분 구문 변경, 예를 들어 파일 번호를 명시적으로 설정하는 등)NR == FNR트릭) :

awk '{if (f==1) { r[$0] } else if (! ($0 in r)) { print $0 } } ' f=1 exclude-these.txt f=2 from-this.txt

액세스r[$0]그럼 해당 행의 엔트리가 작성되므로 값을 설정할 필요가 없습니다.

awk가 일정한 룩업과 (평균) 일정한 업데이트 시간을 가진 해시 테이블을 사용한다고 가정하면, 이 시간의 복잡도는 O(n + m)가 됩니다.여기서 n과 m은 파일의 길이입니다.내 경우 n은 2500만, m은 14000입니다.awk 솔루션은 종류보다 훨씬 빨랐고, 원래의 주문을 유지하는 것을 선호했습니다.

Ruby (1.9+)가 있는 경우

#!/usr/bin/env ruby 
b=File.read("file2").split
open("file1").each do |x|
  x.chomp!
  puts x if !b.include?(x)
end

O(N^2) 복잡성이 있습니다.퍼포먼스를 중시하는 경우는, 다음의 버전을 참조해 주세요.

b=File.read("file2").split
a=File.read("file1").split
(a-b).each {|x| puts x}

해시를 사용하여 감산에 영향을 미치므로 복잡도 O(n)(a의 크기) + O(n)(b의 크기)도 마찬가지입니다.

다음은 사용자 576875의 제공으로 위의 10만 회선에 대한 벤치마크입니다.

$ for i in $(seq 1 100000); do echo "$i"; done|sort --random-sort > file1
$ for i in $(seq 1 2 100000); do echo "$i"; done|sort --random-sort > file2
$ time ruby test.rb > ruby.test

real    0m0.639s
user    0m0.554s
sys     0m0.021s

$time sort file1 file2|uniq -u  > sort.test

real    0m2.311s
user    0m1.959s
sys     0m0.040s

$ diff <(sort -n ruby.test) <(sort -n sort.test)
$

diff는 생성된 2개의 파일 간에 차이가 없음을 나타내기 위해 사용되었습니다.

다른 다양한 답변의 타이밍 비교:

$ for n in {1..10000}; do echo $RANDOM; done > f1
$ for n in {1..10000}; do echo $RANDOM; done > f2
$ time comm -23 <(sort f1) <(sort f2) > /dev/null

real    0m0.019s
user    0m0.023s
sys     0m0.012s
$ time ruby -e 'puts File.readlines("f1") - File.readlines("f2")' > /dev/null

real    0m0.026s
user    0m0.018s
sys     0m0.007s
$ time grep -xvf f2 f1 > /dev/null

real    0m43.197s
user    0m43.155s
sys     0m0.040s

sort f1 f2 | uniq -u어느 파일에서도 여러 번 나타나는 행을 삭제하기 때문에 대칭적인 차이는 없습니다.

comm은 stdin 및 다음 문자열에도 사용할 수 있습니다.

echo $'a\nb' | comm -23 <(sort) <(sort <<< $'c\nb') # a

SQLite 쉘에 적합한 작업인 것 같습니다.

create table file1(line text);
create index if1 on file1(line ASC);
create table file2(line text);
create index if2 on file2(line ASC);
-- comment: if you have | in your files then specify “ .separator ××any_improbable_string×× ”
.import 'file1.txt' file1
.import 'file2.txt' file2
.output result.txt
select * from file2 where line not in (select line from file1);
.q

이거 SED랑 해봤어?

sed 's#^#sed -i '"'"'s%#g' f2 > f2.sh

sed -i 's#$#%%g'"'"' f1#g' f2.sh

sed -i '1i#!/bin/bash' f2.sh

sh f2.sh

'프로그래밍'의 답은 아니지만, 여기 빠르고 더러운 해결책이 있습니다. http://www.listdiff.com/compare-2-lists-difference-tool을 방문하십시오.

큰 파일에는 안 먹히겠지만, 내겐 효과가 있었어.몇 가지 주의:

  • 저는 웹 사이트와 어떤 관계도 없습니다(아직 저를 믿지 않으시면 온라인에서 다른 도구를 검색하시면 됩니다.저는 "set difference list online"이라는 검색어를 사용했습니다).
  • 링크된 웹 사이트는 목록 비교 시마다 네트워크 호출을 하는 것 같으므로 기밀 데이터를 입력하지 마십시오.

다른 목록을 사용하여 한 목록을 필터링하는 Python 방법입니다.

파일 로드:

>>> f1 = open('f1').readlines()
>>> f2 = open('f2.txt').readlines()

각 행의 끝에 있는 '\n' 문자열을 삭제합니다.

>>> f1 = [i.replace('\n', '') for i in f1]
>>> f2 = [i.replace('\n', '') for i in f2]

f2 파일에 있는 f1 행만 인쇄합니다.

>>> [a for a in f1 if all(b not in a for b in f2)]
$ cat values.txt
apple
banana
car
taxi

$ cat source.txt
fruits
mango
king
queen
number
23
43
sentence is long
so what
...
...

소스 파일에 있는 값들을 "풀"하기 위해 작은 셸 스크립트를 만들었습니다.txt 파일.

$cat weed_out.sh
from=$1
cp -p $from $from.final
for x in `cat values.txt`;
do
 grep -v $x $from.final > $from.final.tmp
 mv $from.final.tmp $from.final
done

실행 중...

$ ./weed_out source.txt

깔끔하게 정리된 파일을 얻을 수 있습니다.

언급URL : https://stackoverflow.com/questions/4780203/deleting-lines-from-one-file-which-are-in-another-file

반응형