한 파일에서 다른 파일에 있는 줄 삭제
파일이 있습니다.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
'programing' 카테고리의 다른 글
NullInjectorError: MatDialogRef에 대한 공급자가 없습니다. (0) | 2023.04.26 |
---|---|
C#에서 2 List를 병합하고 중복된 값을 제거하는 방법 (0) | 2023.04.26 |
프로세스가 완료될 때까지 기다립니다. (0) | 2023.04.21 |
.bat 파일을 사용하여 폴더가 있는지 확인 (0) | 2023.04.21 |
서버 사용방법global.asax의 MapPath()? (0) | 2023.04.21 |