Piping sed to grep ne semble pas fonctionner comme prévu

J'ai 2 files:

$ 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 

Je veux partir de file2 tous les noms qui n'existent pas dans le file1.
Ce qui suit ne fonctionne pas:

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

Pourquoi la pipe à grep -v ne fonctionne pas dans ce cas?

C'est pratiquement la dernière étape de ma réponse à votre question précédente .

Votre solution fonctionne, si vous ajoutez -f devant le file1 dans le grep :

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

Avec le -f , grep cherchera dans le file1 les templates. Sans cela, il utilisera simplement file1 comme model littéral.

Vous pouvez également utiliser -F car sinon, le point du motif sera interprété comme "n'importe quel caractère". Et pendant que vous y êtes, mettez -x là aussi pour faire grep faire le match sur toute la ligne (ce sera utile si vous avez un joe.smith qui ne devrait pas correspondre à joe.smiths ):

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

Cela nécessite évidemment qu'il n'y ait pas d'espaces de fin à la fin des lignes dans le file1 (ce qui semble être dans le text de la question).

Notez que le sed n'est pas nécessaire puisque la sortie de la cut ne contient pas de " . De plus, si vous aviez besoin de tout supprimer " , tr -d '"' aurait été un meilleur outil.

Essaye ça. Non sed . Nécessite GNU diff et bash .

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

Rendements:

 bill.smith tim.jones 

Cela devrait fonctionner:

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

Dans votre exemple, grep manque son model. De plus grep peut lire un file ou un stdin (par pipe) pas les deux. Si le nom de file n'est pas donné alors grep lit de stdin.

En outre, cela pourrait aussi fonctionner:

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

Désolé, ce n'est pas testé.

La réponse avec grep -f est probablement la meilleure, mais une alternative légèrement élégante est:

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

Bien sûr, cela nécessite un file temporaire supplémentaire (ou amusant et des jeux avec des descripteurs de files), et je ne voudrais pas l'essayer avec de gros files.

Je le mentionne uniquement parce que, pour les tâches d'appariement entre files, le sort plus uniq est une paire d'outils inattendue, polyvalente et peut-être sous-estimée. Pour des tâches rapides, ils peuvent fournir un moyen peu réfléchi à un résultat.