両方のファイルの最初の類似行と一致します。

両方のファイルの最初の類似行と一致します。

2つのファイルセットがあります。

ファイル1には次のIDが含まれています。

1111
2222
6666
3333
4444

ファイル2にはIDとユーザー名が含まれています。

1873 Neil
1111 Roger
7632 Tim
3333 Oscar
8723 Greg
4444 Roy
6666 Patrick

IDとユーザー名を抽出したいのですが、ファイル1のIDと同じ項目だけを抽出したいと思います。grep -f file1 file2公開したばかりのように、IDがほとんどない状態で作成された2つのテストファイルに対して通常の作業を行いました。ただし、これを2つの正しいファイルに適用すると、file1には3500個のIDがあり、File2には12000個のID +ユーザー名が含まれ、両方のファイルに表示される3500行を抽出する代わりに12000行を抽出します。ただし、2つのテストファイルといくつかのダミーIDを使用して正しいIDのみを抽出し、残りを維持します。

何が問題なのかについてのアドバイスはありますか?

答え1

以下を使ってこれを行います。代わりにgrep、これがより適切になります:

$ join  <(sort file1) <(sort file2)

1111 Roger
3333 Oscar
4444 Roy
6666 Patrick

シェルが欠落している場合プロセスの交換 <( )、あなたはできます:

sort file1 > new_file1
sort file2 > new_file2
join new_file1 new_file2

医者はこう言いました。

Joinは、同じ結合フィールドを持つ各入力行のペアを標準出力に書き込みます。

バラよりhttp://www.gnu.org/software/coreutils/manual/html_node/join-inspiration.html

指示:

これが正しく機能するには、ソートキーに基づいてファイルをソートする必要がありますjoin。これがまさに私たちがいくつかを使う理由です。ファイル記述子バックグラウンドで使用プロセスの交換 バラよりhttp://mywiki.wooledge.org/ProcessSubstitutionまたはhttp://mywiki.wooledge.org/BashFAQ/024一般的な用途。

答え2

grepユーザー名とIDが同じ行に一致します。join最初のフィールドの一致は正しく制限されますが、ソートされた入力が必要です。入力に応じてawk良い選択かもしれません。

awk 'FNR == NR { ids[$1]++; next } ids[$1]' ids users

またはもっと読みやすくするには:

awk 'FNR == NR { ids[$1]; next } $1 in ids' ids users

出力:

1111 Roger
3333 Oscar
4444 Roy
6666 Patrick

説明する

awkプログラムは2つの部分に分けられます。最初のファイルを評価する部分と2番目のファイルを評価する部分です。

最初のブロックは最初のファイルに対してのみ評価され、IDが配列idsに格納されます。読み込み中にこれらのIDが見つかると、usersデフォルトのblock()が呼び出されます{print $0}

関連情報