2012-04-26 28 views
9

おそらく、これはシェルプログラマにとって非常に基本的な質問です。 テキストファイルAとBがあるとします。 とBはAのサブセットです。基本的なシェルプログラミング

(A-B)データを含むテキストファイルCを作成します。

すべての共通線を省略してください。

id , some aspect, other aspec. 

おかげのように:

ファイル内の行は、数値データです。

+0

あなたは、どちらの方法に言及していない、あなたのデータは重複行を含めることができるかどうか。できれば、Tim Poteの 'sort' +' uniq'メソッド**が動作しないことに注意してください。 'awk'と' comm'メソッドは 'A'で重複して動作します。 –

答えて

12

使用sortuniq

sort a b | uniq -u 

あなたはAとBの間に同じ行をしたい場合は、あなたがuniq -d

sort a b | uniq -d 

を使用することができますこれはAのデータという当然の前提としBは正確にはと同じです。データセット内にスペースやタブを失うことはありません。存在する場合は、sed,tr、またはawkを最初に使用してデータをクリーンアップする必要があります。ピーターとして

編集

。 Oが指摘した場合、ファイルaに正確な重複があると、これは失敗します。 awkを使用して

sort <(sort -u a) b | uniq -u 
+0

非常に素朴な質問です。ファイル "c"にどのように保存するのですか? – Fraz

+1

出力を '>'でリダイレクトする必要があります。したがってコマンドは次のようになります: 'sort a b |ユニーク-u> c' –

+1

'ソートa b |ユニーク-u> c' – dpp

4

一つの方法:それが問題だ場合、あなたはこれを行うことによってそれを修正することができます。 STDOUTではなく、ファイルにコンテンツを保存するようにリダイレクトします。

awk 'FNR == NR { data[ $0 ] = 1; next } FNR < NR { if ($0 in data) { next } print $0 }' fileB fileA 

は、より効率的なコマンドでを更新しました。 Peter.Oのおかげ:

comm -23 A B > C 

-2は「Bをファイルに独自の行を拒否」を意味します(あなたがそこに上がらないと言う:

awk 'FNR==NR{data[$0]; next}; $0 in data{next}; 1' fileB fileA 
+0

もう少し納得のいく(そしてより速く)ためにちょっとしたポイント:1)配列に値を割り当てる必要はありません。それを参照するだけで、インデックス部分が作成されます。 2)第2のFNR検査は、前の「次の」検査が必要であるため、必要ではない。 3) 'if $'テストはそれ自体のテストであるため、 'if'テストは余計です。 4)ゼロ以外の値を指定すると、 '$ 0'が印刷されるので、' print $ 0'は "ブール値"になります: 'awk 'FNR == NR {data [$ 0];次};データ{0}の$ 0; 1 'fileB fileA' –

+0

@ Peter.O:提案していただきありがとうございます。私はあなたの命令を答えに加えます。 – Birei

+0

また、null文(末尾のセミコロン)を必要とせず、データ$ 0をテストしてから次の行を実行した後に暗黙のプリントを行うと、テストを無効にすることができます。 (ファイルBが巨大で効率が問題でない限り) 'awk 'FNR == NR {data [$ 0]}!(データ内$ 0' fileB fileA')と書くことができます。 –

7

は、このためだけに使われていますcommと呼ばれるユーティリティがあります't any)、および-3は「両方のファイルに共通の行を拒否する」という意味です。

@BartonChittendenは良い点を作る:

comm -23 <(sort A) <(sort B) > C 
+2

両方のファイルは –

+0

私が聞いたことがなかった 'comm'を見せてくれた+1、私も聞いたことのない' <(command) 'を見せてくれた+010 –

+1

これは「プロセス置換」と呼ばれ、コマンドがファイルであるかのように出力します。マニュアルページを参照してください。 –

2
awk 'FNR==NR{a[$0];next}(!($0 in a))' B A