2017-01-02 1 views
4

Ich möchte einige Dateien von meinem grep Befehl ausschließen, denn das ich verwende Parameter:grep Array-Parameter von ausgeschlossenen Dateien

--exclude=excluded_file.ext 

Um leichter zu machen lesen will ich mit ausgeschlossenen ein Bash-Array verwenden Dateien:

EXCLUDED_FILES=("excluded_file.ext") 

Dann $ {} EXCLUDED_FILES Array grep passieren, wie:

grep -Rni "my text" --exclude=${EXCLUDED_FILES} 

Wie kann ich ein Array als Parameter an grep übergeben?

+1

verwenden Sie entweder glob Ausdruck, oder machen Sie einen Patch auf grep. – Kent

+0

Ich habe erfolglos versucht, 'exclude-from' zu verwenden und eine Datei im laufenden Betrieb zu erstellen:' grep ... --exclude-from = "$ (<(printf"% s \ n "" $ {excluded_files [@]} "))" ' – fedorqui

+1

@fedorqui Sie versuchen, den Dateinamen der Prozessvertretung als Befehl auszuführen. Lassen Sie die '$ (...)' fallen. – chepner

Antwort

4

Ich denke, Sie für diese suchen:

grep -Rni "${excluded_files[@]/#/--exclude=}" "my text" 

Der Parameter Expansion "${excluded_files[@]/#/--exclude=}"excluded_files mit jedem Feld mit --exclude= voran den Ausbau des Arrays erweitern.Schauen Sie:

$ excluded_files=('*.txt' '*.stuff') 
$ printf '%s\n' "${excluded_files[@]/#/--exclude=}" 
--exclude=*.txt 
--exclude=*.stuff 
+1

Schön gemacht; weil man es nicht oft sieht, vergisst man leicht, dass solche Parametererweiterungen auch mit _arrays_ funktionieren. – mklement0

+0

Schön gemacht. Bitte erläutern Sie, was $ {exclude_files [@]/#/- exclude =} bedeutet? "/ # /" ist so etwas wie foreach? – daniftodi

+0

@daniftodi: Die Erweiterung '$ {array [@]/pattern/replacement}" 'ist die von' "$ {array [@]}" 'wo das erste Vorkommen von' pattern' durch 'replacement' ersetzt wird Feld des Arrays 'array' Das' # 'Symbol im Muster ist der Anker für den Anfang des Strings. Ebenso ist'% 'der Anker für das Ende des Strings. –

7

Variablen werden nicht als Argumente an Programme übergeben; Werte sind. Variablen (insbesondere Arrays) werden durch die Shell in ein oder mehrere Wörter expandiert und jedes Wort wird als separates Argument an ein Programm übergeben. In diesem speziellen Fall verwendet die Option --exclude einen einzelnen Dateinamen als Argument. Daher müssen Sie mehrere --exclude=foo Argumente aus Ihrem Array erstellen. Eine Option:

for f in "${EXCLUDED_FILES[@]}"; do 
    opts+=(--exclude="$f") 
done 
grep -Rni "my text" "${opts[@]}" 
1

Sie können ein Array nicht als Parameter an einen Befehl übergeben. Alle Parameter sind Strings.

Sie können jedoch Ihr Array in eine Zeichenfolge konvertieren, die alle Array-Elemente enthält, die durch ein Trennzeichen getrennt sind (standardmäßig ein Leerzeichen). Die Syntax würde

grep -Rni "my text" --exclude="${EXCLUDED_FILES[*]}" 

sein Ich möchte darauf hinweisen, jedoch, dass die --exclude Argument GNU grep nicht so funktioniert. Sein Wert wird als ein einzelner Glob genommen, mit dem Ergebnisse gefiltert werden. Dies unterscheidet sich von dem --exclude-from Argument-Verhalten, jede Zeile der Datei als separaten Glob zu behandeln. Wenn Sie mehrere Ausschlussklumpen in der Befehlszeile angeben möchten, müssen Sie für jedes Argument separat ein Argument --exclude angeben.

2

GNU grep unterstützt auch die --exclude-from Option, die einen Dateinamen als Argument, mit den genannten Dateien enthält, die Muster ausschließen, die jeweils in einer eigenen Zeile nimmt.

Wenn Sie Dateinamen mit eingebetteten Zeilenumbrüche nicht besorgt sind (selten eine Sorge), können Sie einen Prozess Substitution wie folgt verwenden eine solche Datei on the fly zu erstellen:

grep -Rni "my text" --exclude-from=<(printf '%s\n' "${EXCLUDED_FILES[@]}") 

Als Nebenbei: Es ist besser, nicht alle Großbuchstaben-Shell-Variablennamen zu avoid conflicts with environment variables and special shell variables zu verwenden.

2

Die GNU Jungs wirklich vermasselt, wenn sie grep Optionen für find ing Dateien gab. Was kommt als nächstes - Optionen zu sort es ist Ausgabe oder tr anslate Zeichen oder drucken Sie nur die head/tail der Ergebnisse? Das UNIX-Tool zum Suchen von Dateien hat den sehr passenden und offensichtlichen Namen find. Das UNIX-Tool grep wird auch treffend benannt " lobally G Letztes Spiel R egular E xpression in einer Datei und P rucken das Ergebnis".

So find finden Dateien während grep drucken Strings aus Dateien, die einen regulären Ausdruck entsprechen - 2 sehr unterschiedliche Zwecke und Sie sollten nur das richtige Werkzeug für jede Aufgabe als die beabsichtigten UNIX-Designer verwenden:

findsarg=() 
for f in "${EXCLUDED_FILES[@]}" 
do 
    findsarg+=('!' -name "$f") 
done 
find . -type f "${findsarg[@]}" -exec grep -Hni "my text" {} + 

Dank @gniourf_gniourf für Hilfe, die Syntax für das Behandeln von Dateinamen, die globbing Metazeichen und Leerraum enthalten, zu erhalten.

Wie an anderer Stelle erwähnt - verwenden Sie nicht alle Großbuchstaben für nicht exportierte Variablen per Konvention und um Konflikte mit exportierten/Standardnamen zu vermeiden.

Verwandte Themen