質問をするために例を使用します。 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の行全体を比較して削除したいと思います。また、結果を3番目のファイル、File#3に保存したいと思います。
答え1
次の目的で使用できますawk
。
awk 'FNR==NR{a[$1];next};!($1 in a)' file1 file2 > file3
説明する:
FNR == NR
:このテストは、レコード数がファイル内のレコード数と等しい場合に真です。 2番目のファイルNR
はfile1 + number of lineと同じであるため、これは最初のファイルにのみ適用されますFNR
。a[$1]
:file1 の最初のフィールドの配列要素インデックスを生成します。next
: 次のレコードに移動し、file1 は処理されなくなりました。!($1 in a)
:最初のフィールド($ 1)が配列、つまりファイル1にあることを確認し、行全体をファイル3に印刷します。
次の例のいずれかに基づいて#awk Wiki。
答え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
2番目のファイルで2番目のループが実行され、正規表現を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)