한 파일에서 다른 파일에있는 행 삭제
파일이 있습니다 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
대신 통신을 시도하십시오 (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 크기) + O (n) (from-this.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의 호의가있는 위의 100K 라인이있는 작은 벤치 마크가 있습니다.
$ 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 '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
참고 URL : https://stackoverflow.com/questions/4780203/deleting-lines-from-one-file-which-are-in-another-file
'IT' 카테고리의 다른 글
django : select_related와 get_object_or_404를 함께 사용 (0) | 2020.07.20 |
---|---|
R을 사용하여 압축 된 데이터 파일 다운로드, 데이터 추출 및 가져 오기 (0) | 2020.07.20 |
javax.el.PropertyNotFoundException 노출 및 해결 : 도달 할 수없는 대상 (0) | 2020.07.20 |
jQuery를 사용하여 30 분 안에 쿠키를 종료하는 방법은 무엇입니까? (0) | 2020.07.20 |
BASH의 목록에 변수가 있는지 확인하는 방법 (0) | 2020.07.20 |