Verhindern Sie die Parametererweiterung im Shell-Skript

8

Ich muss oft eine rekursive Suche in Dateien durchführen. Ich bin es leid, ständig die gesamte Kombination "find / grep" einzugeben, und habe gerade ein Skript mit der folgenden Zeile erstellt:

find . -name $1 -exec grep $2 {} + 2>/dev/null

Die Idee ist, dass ich es zum Beispiel ausführen kann:

myfind '*' hello

Das Problem ist, wenn '*'das Skript an das Skript übergeben wird, erweitert es es auf jede Datei im Verzeichnis.

Ich habe versucht, ein Zitat zu machen $1:

 find . -name '$1' -exec grep $2 {} + 2>/dev/null

Dies wird jedoch $1zu einer Literalzeichenfolge.

Würde mich über Ihre Hilfe bei der Suche nach der richtigen Syntax freuen. Muss etwas Einfaches sein, das mir fehlt.

Peter
quelle

Antworten:

11

Ich habe das Problem hier demonstriert:

$ pie() { echo $1; }; pie '*'
1 2 3 4 5 file

Erweitert. Mühe.

Die Lösung ist jedoch recht einfach. Sie müssen es nur zitieren, aber auf eine Weise, die Bash verstehen wird. Wir verwenden doppelte Anführungszeichen. Es wird durch den variablen Inhalt ersetzt, aber nicht erweitert.

$ pie() { echo "$1"; }; pie '*'
*
Oli
quelle
Vielen Dank. Das war's. Es sollte doppelte Anführungszeichen anstelle von einfachen Anführungszeichen verwendet haben.
Peter
4

Sie müssen sich mit den Grundregeln für die Shell-Erweiterung von Variablen vertraut machen.

NAME="start"

Wenn Sie der Shell $ NAME präsentieren, wird es auf den String- Start erweitert

Wenn Sie eine Zeichenfolge in einfache Anführungszeichen setzen, wird die Shell nicht in den einfachen Anführungszeichen erweitert, sodass '$ NAME' als $ NAME bleibt

Bei doppelten Anführungszeichen erweitert die Shell die Variable $ NAME auf den Zeichenfolgenstart , aber die doppelten Anführungszeichen verhindern das sogenannte Dateiglobbing.

Was ist File Globbing, das Sie fragen?

Nun, das tust du

ls -l *

Sie erwarten, dass der Befehl ls alle Dateien auflistet. Es ist nicht ls, das * in alle Dateinamen im Verzeichnis konvertiert, sondern die Shell.

Angenommen, Sie hatten eine Datei mit dem Namen * in Ihrem Verzeichnis und wollten diese Datei nur auflisten, dann können Sie beide verwenden

ls -l '*' 

oder

ls -l "*"

und sowohl einfache als auch doppelte Anführungszeichen verhindern, dass die Shell das * auf die Liste der Dateien erweitert.

Das Globbing kann auch dadurch deaktiviert werden

set noglob

Anstatt diese einfache Suchzeichenfolge als separates Shell-Skript zu verwenden, bei dem bei jeder Verwendung eine neue Shell aufgerufen werden muss, können Sie sie effizienter als Shell-Funktion fs (find_string) erstellen.

function fs ()
{
 \find . -type f -name "${1}" -exec egrep --color "${2}" {} /dev/null \;
}
JG Miller
quelle