2017-12-08 10 views
0

私は2つのファイルを持っています。一つは最初のフィールドが別のファイルに保存されたリストと一致する場合に行を抽出する - シェルコマンド

Allie 
Bob 
John 
Laurie 

別のファイル(FILE2)が異なる順序で項目の別のリストが含まれていますが、いくつかの項目は、例えば、ファイル1内の項目で

Laurie 45 56 6 75 
Moxipen 10 45 56 56 
Allie 45 56 67 23 
を重複する場合があり、例えば、アイテムのリストが含まれています

私はこれらの2つのファイルを交差し、最初のフィールドフィールド内の項目と一致する1

すなわちファイル2からの行だけを抽出したい、私の出力は

Allie 45 56 67 23 
Laurie 45 56 6 75 
012でなければなりません

(できればこの順であることが好ましいが、それ以外の場合は問題ありません)

grep -f file1 file2私がしたいことはありません。

2番目のファイルが大量であるため、効率的なものも必要です。

また、私はこれを試してみました:

awk -F, 'FNR==NR {a[$1]=$0; next}; $1 in a {print a[$1]}' file2 file1 
+0

[Bashの別の大きなテキストファイルからテキストファイルの行を探す最速の方法](https://stackoverflow.com/questions/42239179/fastest-way-to-find-lines-of-a) -text-file-from-another-larger-text-file-in-bash) – Sundeep

+0

ポインタをありがとう。ではない正確に。 – Bondrak

+0

ソート順を保持する必要がありますか?あなたが参加しているフィールドをソートしたいなら、 'join'コマンドはこの仕事をすることができます(' sort'を使ってインラインで/プロセス置換を行うことができます)。 –

答えて

1

順序は重要ではない場合、

awk 'FNR==NR{ arr[$1]; next }$1 in arr' file1 file2 

説明

  • FNR==NR{ arr[$1]; next }ここでは、最初のファイル(file1)を読んで、arrはインデックスキーの最初のフィールド$1ている配列は、です。
  • $1 in arr最初のファイルの読み込み中に作成された配列arrが2番目のファイルの最初の列であるインデックスキー(インデックスキーが存在する場合は$1 in arrがtrueの場合)を持つ場合、2番目のファイル(file2) FILE2

テスト結果からライン:

[email protected]:/tmp$ cat file1 
Allie 
Bob 
John 
Laurie 

[email protected]:/tmp$ cat file2 
Laurie 45 56 6 75 
Moxipen 10 45 56 56 
Allie 45 56 67 23 

[email protected]:/tmp$ awk 'FNR==NR{ arr[$1]; next }$1 in arr' file1 file2 
Laurie 45 56 6 75 
Allie 45 56 67 23 
0

これはjoinがために構築されている仕事です。

(あなたは、実際の入力ファイルと置き換えることができます)シェル関数でコピー&ペーストを経由してテスト可能な再生装置を提供する:

cat_file1() { 
    printf '%s\n' Allie Bob John Laurie 
} 

cat_file2() { 
    printf '%s\n' 'Laurie 45 56 6 75' \ 
       'Moxipen 10 45 56 56' \ 
       'Allie 45 56 67 23' 
} 

join <(cat_file1 | sort) <(cat_file2 | sort) 

は...適切に発する:

Allie 45 56 67 23 
Laurie 45 56 6 75 

のもちろん、cat file1 | sort - sort <file1を実行して効率を上げるための実際のハンドルを提供するか、入力を最初にソートされた形式で保存してください(より良い!)。

+0

あなたの例はうまくいきました。実際のファイルを入力すると、0行が返されます。理由を理解しようとしています。 – Bondrak

+0

Hmm。入力が 'join 'に到達するまでにキーフィールドでソートされていない場合は何も返しません。これが最も明白ですが、' sort'を通るプロセスの置換はそれを解決するはずです。問題を再現する方法を見つけ出すか、何が起こっているのかを解くために使用できる詳細を提供できるかどうかを教えてください。 –

+0

わかりません。どちらもソートされています。たぶんcharエンコーディング。私はutf-8を扱っています。 – Bondrak

1

コンプレックスの必要は参加し、それは

$ grep -wFf file1 file2 

Laurie 45 56 6 75 
Allie 45 56 67 23 
フィルタリング機能であります

には、file2でも同様のメリットがあります。 -wは、サブストリングの一致を排除して誤検出を防ぐ完全一致のためのオプションです。もちろん、サンプル入力が代表でなく、データに他のフィールドのようなキーのようなエントリが含まれている場合は、行の始まりを指定しなければ動作しません。

+0

私もこれを試しました。それはファイル2の内容を返します...しかし、私が提供したおもちゃのデータで動作します。私は問題がエンコード(utf-8)だと思います。 export LC_ALL = Cと報告してみましょう。 – Bondrak

+0

それは役に立たなかった。 – Bondrak

+0

これは、サンプルファイルが実際のファイルを表していないことを意味します。多分あなたは異なったファイルフォーマット(dos2unix?)を持っています。 'cat -A file2'で手動で検査してください。 'grep -wF somekey file2'を試してみることもできます – karakfa

関連する問題