web-dev-qa-db-fra.com

Sortie de canal à utiliser comme spécification de recherche pour grep sous Linux

Comment puis-je diriger la sortie de grep comme modèle de recherche pour un autre grep?

Par exemple:

grep <Search_term> <file1> | xargs grep <file2>

Je veux la sortie du premier grep comme terme de recherche pour le deuxième grep. La commande ci-dessus traite la sortie du premier grep comme le nom de fichier du deuxième grep. J'ai essayé d'utiliser le -e option pour le deuxième grep, mais cela ne fonctionne pas non plus.

27
Sripal

Si vous utilisez Bash, vous pouvez utiliser des backticks:

> grep -e "`grep ... ...`" files

les -e L'indicateur et les guillemets doubles sont là pour garantir que toute sortie du grep initial qui commence par un trait d'union n'est pas alors interprétée comme une option pour le second grep.

Notez que la double astuce (qui garantit également que la sortie de grep est traitée comme un seul paramètre) ne fonctionne qu'avec Bash. Il ne semble pas fonctionner avec (t) csh.

Notez également que les backticks sont le moyen standard pour obtenir la sortie d'un programme dans la liste des paramètres d'un autre. Tous les programmes n'ont pas un moyen pratique de lire les paramètres depuis stdin comme le fait (f) grep.

8
Alnitak

Vous devez utiliser xargs's -i commutateur:

grep ... | xargs -ifoo grep foo file_in_which_to_search

Cela prend l'option après -i (foo dans ce cas) et en remplace chaque occurrence dans la commande par la sortie du premier grep.

C'est la même chose que:

grep `grep ...` file_in_which_to_search
14
Nathan Fellman

Essayer

grep ... | fgrep -f - file1 file2 ...
12
Paul Tomblin

Je voulais rechercher du texte dans des fichiers (en utilisant grep) qui avaient un certain modèle dans leurs noms de fichiers (trouvés en utilisant find) dans le répertoire courant. J'ai utilisé la commande suivante:

 grep -i "pattern1" $(find . -name "pattern2")

Ici motif2 est le motif dans les noms de fichiers et motif1 est le motif recherché dans les fichiers correspondant à pattern2 .

edit: Pas strictement de la tuyauterie mais toujours lié et très utile ...

4
mcvz

Voici ce que j'utilise pour rechercher un fichier dans une liste:

ls -la | grep 'file-in-which-to-search'
2
Jim Lahman

D'accord, enfreindre les règles car ce n'est pas une réponse, juste une note que je ne peux pas faire fonctionner ces solutions.

% fgrep -f test file

fonctionne bien.

% cat test | fgrep -f - file
fgrep: -: No such file or directory

échoue.

% cat test | xargs -ifoo grep foo file 
xargs: illegal option -- i
usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
             [-L number] [-n number [-x]] [-P maxprocs] [-s size]
             [utility [argument ...]]

échoue. Notez qu'un I majuscule est nécessaire. Si j'utilise ça, tout va bien.

% grep "`cat test`" file

fonctionne un peu en ce sens qu'il renvoie une ligne pour les termes qui correspondent, mais il renvoie également une ligne grep: line 3 in test: No such file or directory pour chaque fichier qui ne trouve pas de correspondance.

Suis-je en train de manquer quelque chose ou s'agit-il simplement de différences dans ma distribution Darwin ou mon shell bash?

1
SidMuchRock

J'ai essayé de cette façon, et cela fonctionne très bien.

[opuser@vjmachine abc]$ cat a
not problem
all
problem
first
not to get
read problem
read not problem

[opuser@vjmachine abc]$ cat b
not problem xxy
problem abcd
read problem werwer
read not problem  98989
123 not problem 345
345 problem tyu

[opuser@vjmachine abc]$ grep -e "`grep problem a`" b --col
not problem xxy
problem abcd
read problem werwer
read not problem  98989
123 not problem 345
345 problem tyu

[opuser@vjmachine abc]$ 
1
Vincent Jia

Vous devriez grep de cette manière, pour extraire uniquement les noms de fichiers, voir le paramètre -l (le L en minuscule):

grep -l someSearch * | xargs grep otherSearch

Parce que sur le simple grep, la sortie est beaucoup plus d'informations que les noms de fichiers uniquement. Par exemple, lorsque vous faites

grep someSearch *

Vous allez diriger vers des informations xargs comme celle-ci

filename1: blablabla someSearch blablabla something else
filename2: bla someSearch bla otherSearch
...

La tuyauterie de l'une des lignes ci-dessus rend absurde le passage à xargs. Mais quand vous faites grep -l someSearch *, votre sortie ressemblera à ceci:

filename1
filename2

Une telle sortie peut maintenant être passée à xargs

0
armagedescu