bash, Linux : 두 텍스트 파일 간의 차이 설정
나는 두 개의 파일이 A- nodes_to_delete및 B- nodes_to_keep. 각 파일에는 숫자 ID가있는 여러 줄이 있습니다.
나는에있는 숫자 ID의 목록을 갖고 싶어 nodes_to_delete하지만,하지에 nodes_to_keep예를
.
PostgreSQL 데이터베이스 내에서 수행하는 것은 비합리적으로 느립니다. Linux CLI 도구를 사용하여 bash에서 깔끔한 방법이 있습니까?
업데이트 : 이것은 Pythonic 작업처럼 보이지만 파일은 정말 정말 큽니다. 내가 사용하는 몇 가지 유사한 문제를 해결 한 uniq, sort어떤 집합 이론 기술을. 이것은 데이터베이스에 상응하는 것보다 약 2-3 배 더 빠릅니다.
통신의 명령은 해당 작업을 수행합니다.
누군가가 몇 달 전 sh에서 정확히이 작업을 수행하는 방법을 보여 주었는데 잠시 동안 그것을 찾을 수 없었습니다 ... 그리고 나는 당신의 질문을 우연히 발견했습니다. 여기있어 :
set_union () {
sort $1 $2 | uniq
}
set_difference () {
sort $1 $2 $2 | uniq -u
}
set_symmetric_difference() {
sort $1 $2 | uniq -u
}
사용 comm-두 개의 정렬 된 파일을 한 줄씩 비교합니다.
질문에 대한 짧은 답변
이 명령은 deleteNodes에 고유 한 행을 리턴하지만 keepNodes의 행은 리턴하지 않습니다.
comm -1 -3 <(sort keepNodes) <(sort deleteNodes)
예시 설정
keepNodes및 라는 파일을 만들고 명령에 deleteNodes대한 정렬되지 않은 입력으로 사용 하겠습니다 comm.
$ cat > keepNodes <(echo bob; echo amber;)
$ cat > deleteNodes <(echo bob; echo ann;)
기본적으로 인수없이 comm을 실행하면 다음 레이아웃으로 3 개의 열이 인쇄됩니다.
lines_unique_to_FILE1
lines_unique_to_FILE2
lines_which_appear_in_both
위의 예제 파일을 사용하여 인수없이 comm을 실행합니다. 세 개의 열에 유의하십시오.
$ comm <(sort keepNodes) <(sort deleteNodes)
amber
ann
bob
열 출력 억제
-N으로 열 1, 2 또는 3을 억제합니다. 열이 숨겨지면 공백이 줄어 듭니다.
$ comm -1 <(sort keepNodes) <(sort deleteNodes)
ann
bob
$ comm -2 <(sort keepNodes) <(sort deleteNodes)
amber
bob
$ comm -3 <(sort keepNodes) <(sort deleteNodes)
amber
ann
$ comm -1 -3 <(sort keepNodes) <(sort deleteNodes)
ann
$ comm -2 -3 <(sort keepNodes) <(sort deleteNodes)
amber
$ comm -1 -2 <(sort keepNodes) <(sort deleteNodes)
bob
정렬이 중요합니다!
먼저 파일을 정렬하지 않고 comm을 실행하면 정렬되지 않은 파일에 대한 메시지와 함께 정상적으로 실패합니다.
comm: file 1 is not in sorted order
comm 이러한 종류의 사용 사례를 위해 특별히 설계되었지만 정렬 된 입력이 필요합니다.
awk세트 차이를 찾는 것이 매우 간단하고, 필요하지 않으며 sort, 추가적인 유연성을 제공 하기 때문에 틀림없이 더 나은 도구입니다 .
awk 'NR == FNR { a[$0]; next } !($0 in a)' nodes_to_keep nodes_to_delete
예를 들어 음수가 아닌 숫자를 나타내는 행의 차이 만 찾고 싶을 수 있습니다.
awk -v r='^[0-9]+$' 'NR == FNR && $0 ~ r {
a[$0]
next
} $0 ~ r && !($0 in a)' nodes_to_keep nodes_to_delete
아마도 postgres에서 더 나은 방법이 필요할 수도 있습니다. 플랫 파일을 사용하여 더 빠른 방법을 찾지 못할 것입니다. 간단한 내부 조인을 수행하고 두 ID 열이 모두 매우 빠르게 인덱싱되었다고 가정 할 수 있어야합니다.
So, this is slightly different from the other answers. I can't say that a C++ compiler is exactly a "Linux CLI tool", but running g++ -O3 -march=native -o set_diff main.cpp (with the below code in main.cpp can do the trick):
#include<algorithm>
#include<iostream>
#include<iterator>
#include<fstream>
#include<string>
#include<unordered_set>
using namespace std;
int main(int argc, char** argv) {
ifstream keep_file(argv[1]), del_file(argv[2]);
unordered_multiset<string> init_lines{istream_iterator<string>(keep_file), istream_iterator<string>()};
string line;
while (getline(del_file, line)) {
init_lines.erase(line);
}
copy(init_lines.begin(),init_lines.end(), ostream_iterator<string>(cout, "\n"));
}
To use, simply run set_diff B A (not A B, since B is nodes_to_keep) and the resulting difference will be printed to stdout.
Note that I've forgone a few C++ best practices to keep the code simpler.
Many additional speed optimizations could be made (at the price of more memory). mmap would also be particularly useful for large data sets, but that'd make the code much more involved.
데이터 세트가 크다고 말씀 하셨기 때문에 nodes_to_delete한 번에 한 줄씩 읽는 것이 메모리 소비를 줄이는 데 좋은 생각이라고 생각했습니다. 위 코드에서 취한 접근 방식은 nodes_to_delete. 또한 질서는 보존되지 않습니다.
복사 및 붙여 넣기가 더 쉬운 것 bash(예 main.cpp: 생성 건너 뛰기 ) :
g++ -O3 -march=native -xc++ -o set_diff - <<EOF
#include<algorithm>
#include<iostream>
#include<iterator>
#include<fstream>
#include<string>
#include<unordered_set>
using namespace std;
int main(int argc, char** argv) {
ifstream keep_file(argv[1]), del_file(argv[2]);
unordered_multiset<string> init_lines{istream_iterator<string>(keep_file), istream_iterator<string>()};
string line;
while (getline(del_file, line)) {
init_lines.erase(line);
}
copy(init_lines.begin(),init_lines.end(), ostream_iterator<string>(cout, "\n"));
}
EOF
참고 URL : https://stackoverflow.com/questions/2509533/bash-linux-set-difference-between-two-text-files
'Program Club' 카테고리의 다른 글
| npm install과 npm run build의 차이점은 무엇입니까? (0) | 2020.11.27 |
|---|---|
| 타이머가 아직 실행 중인지 확인할 수 있습니까? (0) | 2020.11.27 |
| C ++의 정적 변수 (0) | 2020.11.26 |
| Rails3에서 관련 관계에 범위가 지정되지 않은 것을 사용하는 방법은 무엇입니까? (0) | 2020.11.26 |
| div 스크롤바를 왼쪽에 배치하는 방법은 무엇입니까? (0) | 2020.11.26 |