83 votes

grep pour plusieurs chaînes de caractères dans des fichiers sur des lignes différentes (ie. l'ensemble du fichier, pas de ligne de base de la recherche)?

Je veux grep pour les fichiers contenant les mots - Dansk, Svenska ou Norsk sur toute la ligne, avec un utilisable code_retour (que je n'ai vraiment comme d'avoir l'info que les chaînes sont contenues, mon one-liner va un peu plus loin que cela).

J'ai beaucoup de fichiers avec des lignes comme ceci:

Disc Title: unknown
Title: 01, Length: 01:33:37.000 Chapters: 33, Cells: 31, Audio streams: 04, Subpictures: 20
        Subtitle: 01, Language: ar - Arabic, Content: Undefined, Stream id: 0x20, 
        Subtitle: 02, Language: bg - Bulgarian, Content: Undefined, Stream id: 0x21, 
        Subtitle: 03, Language: cs - Czech, Content: Undefined, Stream id: 0x22, 
        Subtitle: 04, Language: da - Dansk, Content: Undefined, Stream id: 0x23, 
        Subtitle: 05, Language: de - Deutsch, Content: Undefined, Stream id: 0x24, 
(...)

Voici le pseudo-code de ce que je veux:

for all files in directory;
 if file contains "Dansk" AND "Norsk" AND "Svenska" then
 then echo the filename
end

Quelle est la meilleure façon de le faire? Peut-il être fait sur une seule ligne?

88voto

vmpstr Points 2302

grep -l Dansk * | xargs grep -l Norsk | xargs grep -l Svenska

utiliser . si vous souhaitez également trouver dans les fichiers cachés:

grep -l Dansk .* | xargs grep -l Norsk | xargs grep -l Svenska

22voto

Edd Steel Points 570

Encore une autre façon en utilisant simplement bash et grep:

Pour un seul fichier "test.txt':

 grep -q Dansk test.txt && grep -q Norsk test.txt && grep -l Svenska test.txt

Imprime test.txt le forum le fichier contient toutes les trois (dans n'importe quelle combinaison). Les deux premiers grep ne pas imprimer du tout (-q) et le dernier imprime uniquement le fichier, si les deux autres ont passé.

Si vous voulez le faire pour chaque fichier dans le répertoire:

 for f in *; do grep -q Dansk $f && grep -q Norsk $f && grep -l Svenska $f; done

9voto

Damodharan R Points 1216

Comment grep pour plusieurs chaînes de caractères dans des fichiers sur des lignes différentes (Utiliser le symbole de canal):

for file in *;do 
   test $(grep -E 'Dansk|Norsk|Svenska' $file | wc -l) -ge 3 && echo $file
done

Notes:

  1. Si vous utilisez des guillemets "" avec votre grep, vous devrez échapper à la pipe comme ceci: \| à la recherche pour Dansk, et Norsk Svenska.

  2. Suppose qu'une ligne a une seule langue.

Procédure pas à pas: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/

4voto

kurumi Points 10096
awk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print "0" }' 

ensuite, vous pouvez attrapez la valeur de retour avec le shell

si vous avez Ruby(1.9+)

ruby -0777 -ne 'print if /Dansk/ and /Norsk/ and /Svenka/' file

2voto

Dennis Williamson Points 105818

C'est un mélange de glenn jackman et kurumi réponses qui permet à un nombre arbitraire de regexes au lieu d'un nombre arbitraire de paroles ou d'un ensemble fixe de regexes.

#!/usr/bin/awk -f
# by Dennis Williamson - 2011-01-25

BEGIN {
    for (i=ARGC-2; i>=1; i--) {
        patterns[ARGV[i]] = 0;
        delete ARGV[i];
    }
}

{
    for (p in patterns)
        if ($0 ~ p)
            matches[p] = 1
            # print    # the matching line could be printed
}

END {
    for (p in patterns) {
        if (matches[p] != 1)
            exit 1
    }
}

L'exécuter comme ceci:

./multigrep.awk Dansk Norsk Svenska 'Language: .. - A.*c' dvdfile.dat

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X