첫 번째 열과 두 파일을 비교하고 셸 스크립트의 두 번째 파일에서 중복 행을 제거하십시오.


9

예를 들어 질문을하겠습니다. 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

첫 번째 열을 사용하여 파일 1과 파일 2를 비교하고 파일 1에서 일치하는 파일 2에서 전체 줄이나 행을 제거하고 싶습니다. 또한 결과를 세 번째 파일 인 파일 # 3에 저장하고 싶습니다.

답변:


10

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

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

설명:

  • FNR == NR:이 테스트는 레코드 수가 파일의 레코드 수와 같을 때 적용됩니다. 이것은 첫 번째 파일에만 해당되며 두 번째 파일 NR은 file1 +의 행 수와 같습니다 FNR.

  • a[$1]: file1의 첫 번째 필드의 배열 요소 색인을 작성하십시오.

  • next: file1에서 더 이상 처리되지 않도록 다음 레코드로 건너 뜁니다.

  • !($1 in a): 첫 번째 필드 ($ 1)가 배열, 즉 file1에 있는지 확인하고 전체 행을 file3에 인쇄하십시오.

#awk wiki 의 예제 중 하나를 기반으로 합니다.


완벽한 답변 !!!
mtk

8
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).


2

재미를 위해 여기 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. 그것은 주위에 parens를 감싸서 저장됩니다. 이 .*줄에 다른 모든 것을 일치시킵니다.

그 라인의 다음 비트는 우리가 저장하는 열 1 비트 조회 말한다 $1%names해시를 :

$names{$1}

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


2

방법 1 # 배쉬

#!/usr/bin/env bash
file1=$1
file2=$2

[[ $# -ne 2 ]]  && { echo -e "\n\tUsage: \t$0 file1 file2\n"; exit 1; }

while read line
do

        if ! grep -q "${line%% .*}" $file1; then
                echo "${line}"
        fi

done < $file2

방법 2 # Grep 만

grep -v "$(< file1)" file2

grep은 작동하지만 보증은 아닙니다


1

그것을 얻을 수 있습니다

파일 # 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)

이것은 전체 줄이 동일한 경우에만 작동하지만 질문자는 첫 번째 열에서만 명시 적으로 비교를 요청했습니다.
Adaephon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.