sedからgrepへのパイピングが期待どおりに機能しないようです。

sedからgrepへのパイピングが期待どおりに機能しないようです。

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

$ cat file1  
jim.smith  
john.doe  
bill.johnson  
alex.smith  

$ cat file2   
"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321      
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976     
"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243  
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233  

file1にないfile2のすべての名前を取得したいと思います。
以下は機能しません:

$ cut -d, -f 3 file2 | sed 's/"//g' | grep -v file1  
jim.smith  
tim.jones  
john.doe  
bill.smith  

この場合、パイプのgrep -vが機能しないのはなぜですか?

答え1

実際、これは私の最後のステップです。前の質問に答えるには

-f前に追加する場合:file1grep

$ cut -d, -f3 file2 | grep -v -f file1
tim.jones
bill.smith

を使用すると-fパターンがgrep見つかりますfile1。この機能がなければ、単にfile1テキストモードで動作します。

以降を使用することもできます-F。それ以外の場合、パターンの点は「すべての文字」として解釈されます。また、行全体が一致する-xように入力することもできます(一致しない行がある場合は便利です)。grepjoe.smithjoe.smiths

$ cut -d, -f3 file2 | grep -v -F -x -f file1

明らかに、これは行の末尾に末尾のスペースを必要としませんfile1(質問テキストにあるようです)。

sed出力にcutが含まれていないため、これは必要ありません"。また、必要すべてを削除する"と、tr -d '"'より良いツールになります。

答え2

この試み。sedいいえGNUdiffbash

diff --new-line-format="" --unchanged-line-format="" <(cut -f3 -d, file2|sort) <(sort file1)

収量結果:

bill.smith
tim.jones

答え3

これは働きます:

$ pattern=$(cut -d, -f 3 file2)
$ grep -v -e "$pattern" file1  

あなたの場合、grepはパターンを見逃しました。さらに、grepはファイルまたは標準入力(パイプを介して)を読み取ることができますが、どちらも読み取ることはできません。ファイル名が指定されていない場合、grepはstdinから読み込まれます。

または、次のように機能することもできます。

$ grep -v -f <(cut -d, -f3 file1) file2  

申し訳ありません。まだテストされていません。

答え4

答えはgrep -fおそらく最高です。しかし、少し洗練された代替案は次のとおりです。

% cut -d, -f3 file2 >names2
% cat file1 file1 names2 | sort | uniq -u
bill.smith
tim.jones
%

もちろん、これには追加の一時ファイル(またはファイル記述子を持つ楽しさとゲーム)が必要であり、大きなファイルを使用したくありません。

私がこれを言及する理由は、ファイル間の一致に関連するタスクの場合、プラスがsort驚くuniqほど汎用性があり、おそらく過小評価されたツールのペアであるためです。クイックタスクの場合は、結果を得るための簡単な方法を提供できます。

関連情報