두 파일을 첫 번째 열과 비교하고 쉘 스크립트의 두 번째 파일에서 중복 행을 제거합니다.

두 파일을 첫 번째 열과 비교하고 쉘 스크립트의 두 번째 파일에서 중복 행을 제거합니다.

질문을 하기 위해 예를 사용하겠습니다. 2개의 파일이 있습니다.

파일 1:

118D FC300_R5_TP  FX.B      32775       2112   6       2038   6       2112   0
118E FC300_R5_TP  FX.B      32775       2136   7       2065   6       2136   0
118F FC300_R5_TP  FX.B      32775       2124   6       2064   6       2124   0
1190 FC300_R5_TP  FX.B     819210     814632  99     814609  99     814632   0
1191 FC300_R5_TP  FX.B     819210     104100  13     103714  13     104100   0
1192 FC300_R5_TP  FX.B    1638420    1609476  98    1609402  98    1609476   0
1196 FC300_R5_TP  FX.B    1638420    1638432 100    1638379 100    1638432   0
119A FC300_R5_TP  FX.B    3276840    3271776 100    3271698 100    3271776   0
119E FC300_R5_TP  FX.B    3276840    3264120 100    3264034 100    3264120   0
11A2 FC300_R5_TP  FX.B    3276840    2328648  71    2328546  71    2328648   0
11A6 FC300_R5_TP  FX.B    3276840    2328444  71    2328355  71    2328444   0
11AA FC300_R5_TP  FX.B    3276840    2328528  71    2328403  71    2328528   0
11AE FC300_R5_TP  FX.B    3276840    2328648  71    2328468  71    2328648   0
11B2 FC300_R5_TP  FX.B    3276840    2130000  65    2129766  65    2130000   0
173A FC300_R5_TP  FX.B    6553680    6478572  99    6477747  99    6478572   0

문서 #2:

11AA FC300_R5_TP  FX.B    3276840    2328528  71    2328403  71    2328528   0
11AE FC300_R5_TP  FX.B    3276840    2328648  71    2328468  71    2328648   0
11B2 FC300_R5_TP  FX.B    3276840    2130000  65    2129766  65    2130000   0
173A FC300_R5_TP  FX.B    6553680    6478572  99    6477747  99    6478572   0
0BDB FC600_R5_TP  FX.B   33554640    6044364  18    6033105  18    6044364   0
0BDC FC600_R5_TP  FX.B   33554640    6613536  20    6481974  19    6613536   0
0BDD FC600_R5_TP  FX.B   33554640    4435848  13    4057170  12    4435848   0
0BDE FC600_R5_TP  FX.B   33554640    6620868  20    6249518  19    6620868   0

원하는 출력

문서 #3:

0BDB FC600_R5_TP  FX.B   33554640    6044364  18    6033105  18    6044364   0
0BDC FC600_R5_TP  FX.B   33554640    6613536  20    6481974  19    6613536   0
0BDD FC600_R5_TP  FX.B   33554640    4435848  13    4057170  12    4435848   0
0BDE FC600_R5_TP  FX.B   33554640    6620868  20    6249518  19    6620868   0

file1과 file2의 첫 번째 열을 사용하여 file1에서 일치하는 file2의 전체 행을 비교하고 삭제하고 싶습니다. 또한 결과를 세 번째 파일인 File #3에 저장하고 싶습니다.

답변1

다음을 위해 사용할 수 있습니다 awk:

awk 'FNR==NR{a[$1];next};!($1 in a)' file1 file2 > file3

설명하다:

  • FNR == NR: 이 테스트는 레코드 수가 파일의 레코드 수와 같을 때 참입니다. 두 번째 파일 NR은 file1 + number of line 과 같기 때문에 이것은 첫 번째 파일에만 적용됩니다 FNR.

  • a[$1]: file1의 첫 번째 필드의 배열 요소 인덱스를 생성합니다.

  • next: 다음 레코드로 이동하여 file1이 더 이상 처리되지 않습니다.

  • !($1 in a): 첫 번째 필드($1)가 배열, 즉 파일 1에 있는지 확인하고 전체 줄을 파일 3에 인쇄합니다.

다음 예 중 하나를 기반으로#awk 위키.

답변2

export LC_ALL=C
comm -13 <(sort f1) <(sort  f2)

에 대해서만 보고합니다 f2.

export LC_ALL=C
join -v2 <(sort f1) <(sort f2)

첫 번째 필드를 찾을 수 없는 행은 f2모든 행의 첫 번째 필드로 보고됩니다 f1.

(프로세스 대체를 지원하는 쉘이 필요합니다(예: ksh93, zsh또는 bash).

답변3

재미를 위해 Perl 솔루션은 다음과 같습니다.

#!/usr/bin/perl

# create names lookup table from first file
my %names;
while (<>) {
    (my $col1)= split / /, $_;
    $names{$col1} = 1;
    last if eof;
}

# scan second file
while (<>) {
    print if /^(\S+).*/ && not $names{$1};
}

$ ./showdiffs.pl file1  file2
0BDB FC600_R5_TP  FX.B   33554640    6044364  18    6033105  18    6044364   0
0BDC FC600_R5_TP  FX.B   33554640    6613536  20    6481974  19    6613536   0
0BDD FC600_R5_TP  FX.B   33554640    4435848  13    4057170  12    4435848   0
0BDE FC600_R5_TP  FX.B   33554640    6620868  20    6249518  19    6620868   0

세부 사항

위의 Perl 솔루션은 2개의 루프로 구성됩니다. 첫 번째 루프는 모든 행을 읽고 식별된 각 열을 추가하는 file1해시를 생성합니다 .%names

$names{11AA} = 1;

그런 다음 while두 번째 파일에서 두 번째 루프가 실행되고 file2정규식을 사용하여 각 행의 열 1을 식별합니다.

^(\S+).*

줄의 시작 부분부터 시작하여 공백이 아닌 모든 항목을 일치시키고 임시 변수에 저장하라는 내용입니다 $1. 괄호로 묶어서 저장할 수 있습니다. .*라인의 다른 모든 것과 일치한다고 말합니다 .

줄의 다음 비트는 방금 해시에 저장한 $1열 1비트 를 찾도록 지시합니다 %names.

$names{$1}

존재한다면 인쇄하고 싶지 않습니다. 존재하지 않는 경우 인쇄하십시오.

답변4

우리는 그것을 생각하자

파일 #1: file1.txt

파일 #2: file2.txt

그런 다음 터미널에서 다음 명령을 실행하십시오.

fgrep -vf test1.txt test2.txt > output.txt

output.txt에는 원하는 결과가 포함됩니다.

설명하다:

fgrep : print lines matching a pattern (from manual page)
-v  : get only non-matching rows
-f : obtain PATTERN from FILE (from manual page)

관련 정보