it-swarm.com.de

grep für mehrere Zeichenfolgen in einer Datei in verschiedenen Zeilen (dh ganze Datei, nicht zeilenbasierte Suche)?

Ich möchte für Dateien, die die Wörter Dansk, Svenska oder Norsk enthalten, in einer beliebigen Zeile mit einem verwendbaren Returncode grep (da ich wirklich nur die Informationen haben möchte, dass die Zeichenketten enthalten sind, geht mein Einzeiler dann etwas weiter).

Ich habe viele Dateien mit Zeilen wie folgt:

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, 
(...)

Hier ist der Pseudocode dessen, was ich will:

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

Was ist der beste Weg, dies zu tun? Kann es in einer Zeile gemacht werden?

76
Christian

Sie können verwenden: 

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

Wenn Sie auch in versteckten Dateien suchen möchten:

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

Noch eine andere Möglichkeit, nur bash und grep zu verwenden:

Für eine einzelne Datei 'test.txt':

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

Gibt test.txt aus, wenn die Datei alle drei enthält (in beliebiger Kombination). Die ersten beiden Greps drucken nichts (-q) und der letzte druckt die Datei nur, wenn die anderen beiden übergeben wurden.

Wenn Sie dies für jede Datei im Verzeichnis tun möchten:

 für f in *; do grep -q Dansk $ f && grep -q Norsk $ f && grep -l Svenska $ f; erledigt
21
Edd Steel
grep –irl Word1 * | grep –il Word2 `cat -` | grep –il Word3 `cat -`
  • -i macht Groß- und Kleinschreibung unempfindlich
  • -r macht die Dateisuche rekursiv durch Ordner
  • -l leitet die Liste der Dateien mit dem gefundenen Word weiter
  • cat - bewirkt, dass der nächste grep die an die Liste weitergeleiteten Dateien durchsucht.
12
Gerry

Wie grep ich mehrere Strings in einer Datei in verschiedenen Zeilen (Verwenden Sie das Pipe-Symbol):

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

Anmerkungen:

  1. Wenn Sie mit Ihrem grep doppelte Anführungszeichen "" verwenden, müssen Sie die Pipe wie folgt verlassen: \|, um nach Dansk, Norsk und Svenska zu suchen.

  2. Nimmt an, dass eine Zeile nur eine Sprache hat.

Walkthrough: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/

9
Damodharan R

Mit ack ist das ganz einfach möglich:

ack -l 'cats' | ack -xl 'dogs'
  • -l: Gibt eine Liste von Dateien zurück 
  • -x: Nimm die Dateien von STDIN (die vorherige Suche) und durchsuche nur diese Dateien

Und Sie können einfach weiterpfeifen, bis Sie die gewünschten Dateien erhalten.

5
Ben Johnson

Dadurch werden mehrere Wörter in mehreren Dateien gesucht:

egrep 'abc|xyz' file1 file2 ..filen 
5
Sarath Chandra
awk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print "0" }' 

sie können den Rückgabewert dann mit der Shell abrufen

wenn Sie Ruby haben (1.9+)

Ruby -0777 -ne 'print if /Dansk/ and /Norsk/ and /Svenka/' file
4
kurumi

Einfach:

grep 'Word1\|Word2\|Word3' *

siehe diesen Beitrag für weitere Informationen

3
moshe beeri

Dies ist eine Mischung aus den Antworten von glenn jackman und kurumi, die eine beliebige Anzahl von Regexen anstelle einer beliebigen Anzahl von festen Wörtern oder einer festen Menge von Regex erlaubt.

#!/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
    }
}

Führen Sie es so aus:

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

Erweitere die @ awumi-Antwort von @ kurumi. Hier eine Bash-Funktion:

all_Word_search() {
    gawk '
        BEGIN {
            for (i=ARGC-2; i>=1; i--) {
                search_terms[ARGV[i]] = 0;
                ARGV[i] = ARGV[i+1];
                delete ARGV[i+1];
            }
        }
        {
            for (i=1;i<=NF; i++) 
                if ($i in search_terms) 
                    search_terms[$1] = 1
        }
        END {
            for (Word in search_terms) 
                if (search_terms[Word] == 0) 
                    exit 1
        }
    ' "[email protected]"
    return $?
}

Verwendungszweck:

if all_Word_search Dansk Norsk Svenska filename; then
    echo "all words found"
else
    echo "not all words found"
fi
1
glenn jackman

Was für mich gut funktioniert hat:

find . -path '*/.svn' -Prune -o -type f -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \;
./path/to/file1.sh
./another/path/to/file2.txt
./blah/foo.php

Wenn ich nur .sh-Dateien mit diesen drei Dateien finden wollte, hätte ich Folgendes verwenden können:

find . -path '*/.svn' -Prune -o -type f -name "*.sh" -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \;
./path/to/file1.sh
1
Nick Henry

Ich habe das mit zwei Schritten gemacht. Erstellen Sie eine Liste mit csv-Dateien in einer Datei .__ Mit Hilfe dieser Seitenkommentare habe ich zwei skriptlose Schritte ausgeführt, um das zu bekommen, was ich brauchte. Tippen Sie einfach in das Terminal:

$ find /csv/file/dir -name '*.csv' > csv_list.txt
$ grep -q Svenska `cat csv_list.txt` && grep -q Norsk `cat csv_list.txt` && grep -l Dansk `cat csv_list.txt`

es tat genau das, was ich brauchte - Dateinamen mit allen drei Wörtern drucken. 

Beachten Sie auch die Symbole wie `' "

1
Simas

Ich hatte dieses Problem heute, und alle Einzeiler hier versagten mir, weil die Dateien Leerzeichen in den Namen enthielten.

Das ist, worauf ich gekommen bin, das funktioniert hat:

grep -ril <Word1> | sed 's/.*/"&"/' | xargs grep -il <Word2>
0
giusti

Wenn Sie nur zwei Suchbegriffe benötigen, besteht der lesbarste Ansatz wahrscheinlich darin, jede Suche auszuführen und die Ergebnisse zu schneiden:

 comm -12 <(grep -rl Word1 . | sort) <(grep -rl Word2 . | sort)
0
Ankur Dave