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.
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.
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
Essayer
grep ... | fgrep -f - file1 file2 ...
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 ...
Voici ce que j'utilise pour rechercher un fichier dans une liste:
ls -la | grep 'file-in-which-to-search'
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?
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]$
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