Arg-Behandlung in einem Skript für eine modifizierte "find" -Funktion?

378
Stilez

Ich benutze FreeBSD und verstehe und verwende die -pruneOption on find, um zu verhindern, dass der Befehl in ein Unterverzeichnis absteigt. Aber ich finde die notwendige Syntax sehr unbeholfen und unbeholfen. Es verhindert auch nicht, dass das beschnittene dir angezeigt wird, was zwar fixierbar, aber ärgerlich ist.

Ich möchte ein kurzes Skript / Alias ​​erstellen, das bewirkt -noenter, dass dem findBefehl ein neues Argument hinzugefügt wird, wenn es vor allen anderen Primärfarben (zur Vereinfachung) angegeben wird.

Das Ziel ist, dass ich Folgendes eingeben kann:

  • find -xs /dir -noenter '$*' -name '*.conf' -ls
  • find -x -s /dir -noenter '$*' -name '*.conf' -ls

und es werden die Argumente konvertieren und ausführen:

  • /usr/bin/find -xs /dir \( -name '$*' -prune -or \( -name '*.conf' -and ! \( -type d -and -name '$*' \) \) \) -ls
  • /usr/bin/find -x -s /dir \( SNIPPED \) -ls

aber ich kann auch wie gewohnt jeden routinemäßigen "find" -Befehl eingeben und er wird es transparent übergeben, /usr//bin/findum ihn auszuführen.

Logisch muss das Skript das erste Argument nach dem dir-Namen identifizieren und dann prüfen, ob es

  • ... gleich -noenterund gefolgt von mindestens 2 weiteren Argumenten (in diesem Fall weiß ich, wie ich das Argument aufbauen muss, zu dem ich übergehen muss, /usr/bin/findindem ich weiß, welche Argumente vorher / nachher waren); oder
  • ... gleich -noenteraber nicht gefolgt von mindestens 2 weiteren Argumenten (= Fehler); oder
  • ... etwas anderes oder dir war das letzte Argument oder wurde nicht gefunden (= gib die gesamten ursprünglichen Argumente /usr/bin/findunverändert weiter).

Ich kann alles bis auf eine Sache tun - wie kann ich den Teil des Skripts codieren, der argv untersucht, um herauszufinden, welche arg-Nummer (falls vorhanden) das dirArgument ist?

Meine Shell-Wahl ist shfür das Scripting.

3

1 Antwort auf die Frage

1
gmelis

Wenn Sie das Vorhandensein und den Ort eines bestimmten Arguments testen möchten, müssen Sie lediglich die Befehlszeile analysieren und jedes Argument auf Übereinstimmung mit Ihrem "erwarteten" Wert testen. Sie müssen also jedes Argument auf den Wert testen -noenterund dann eine Zeile mit Position und Name der Variablen ausgeben -noenter:

for i in `seq 1 $#`; do ref=`eval "echo \\$$i"` if [ $ref == '-noenter' ]; then echo "arg $i is $ref"; break; fi done 

Nun wird dasselbe, nur die Position des Arguments -noenterin $mitsosund die Position des Arguments davor gespeichert $mary:

for i in `seq 1 $#`; do ref=`eval "echo \\${$i}"` if [ $ref == '-noenter' ]; then mitsos=$i eva=$(($i-1)) mary=`eval "echo \\${$eva}"` break fi done 

und hat jetzt $mitsosdie Position von -noenteroder keinen Wert und $maryden Wert des vorangehenden Arguments -noenter. Wenn zu diesem Zeitpunkt $maryder Wert vorhanden ist, von dem /dirSie wissen, dass das nächste Argument lautet -noenter, können Sie mit der Implementierung fortfahren. findAndernfalls verwenden Sie die Systemversion oder geben eine Fehlermeldung aus. Wenn Sie sich nicht für die Position von -noenterIhnen interessieren, können Sie die Zeile weglassen mitsos=$i.

Danke für das Verständnis, was ich wollte! Die Antwort ist nicht richtig. Es wird davon ausgegangen, dass -noenter in jeder Position gültig ist und nur danach sucht, aber das ist keine korrekte Annahme (`find -x -noenter .....` sollte ein Fehler sein). Es muss das Argument nach dem "dir" speziell überprüft werden, denke ich? Ich kann es wahrscheinlich aus dem, was Sie geschrieben haben, herausfinden, also ist es extrem nah. Möchten Sie die Antwort bearbeiten, damit ich sie annehmen kann, oder? Stilez vor 6 Jahren 0
Das ist kein Problem, denn auf diese Weise haben Sie eine Variable mit der * Position * von '-noenter' oder keiner Variablen. Sie können also den Wert der Variablen "$ eva" überprüfen, wobei "eva = $ (($ mitsos-1))" ist und wenn das Argument an Position "$ eva" nicht gleich "dir" ist, fahren Sie mit der Implementierung fort , sonst verwenden Sie das System. Ich werde die Antwort bearbeiten, um das zu reflektieren. gmelis vor 6 Jahren 0
Diese Art von Arbeiten. Ich nehme an, dass es aufgrund eines benutzerdefinierten Befehls script / mod möglich ist, dass Fehlaufruf vorerst als Randfall betrachtet wird :) Ich würde es nicht gerne an andere weitergeben, ohne ein bisschen mehr nach gültiger Syntax zu suchen, aber das ist nur mein gefühl :) Stilez vor 6 Jahren 0
Die Methode ist richtig, aber ich habe gerade festgestellt, dass die Eval-Aussage falsch ist. behandelt nicht mehrere Leerzeichen oder> = 10 Argumente. Abhängig von Ihnen behandeln diese die folgenden Probleme: "eval" echo "$ {'$ i'}" "" (Ausgabe) oder "eval" value = "$ {'$ i'}" "(Zuweisung). Beachten Sie das Beenden + Starten der Anführungszeichen, um "$ i" als Wert anstelle des umgekehrten Schrägstrichs + $ aufzunehmen. Shell-Lookalikes werden in der Befehlszeile immer noch nicht behandelt, z. B. `\ (` oder `|`, nicht sicher, was dagegen unternommen werden kann. Sie können nur Kredit erhalten. Wenn es jedoch einfach ist, können Sie ein Update durchführen oder zumindest ein Update durchführen die Ausnahmen, damit andere ein besseres Ergebnis erzielen, wenn sie diese Antwort verwenden? Stilez vor 6 Jahren 0
Ich habe die Antwort für mehr als 9 Argumente aktualisiert. Sie können nur geschweifte Klammern verwenden, wenn Sie keine einfachen Anführungszeichen verwenden, was manchmal störend sein kann. Die Flucht wird wahrscheinlich mehr von dem Problem sein, und die Pfeife ist höchstwahrscheinlich ein Dealbreaker, aber ich werde sehen, ob ich zumindest einen Ausweg finden kann. gmelis vor 6 Jahren 0
Ich denke, es gibt zwei Aspekte: Holen Sie das Argument in eine Variable, basierend auf ihrem numerischen Index, und geben Sie dann sicher an, eine andere Funktion als Argument zu übergeben. Basierend auf Ihren Hinweisen funktionierten diese sehr gut: `eval 'vraw =" $ {' $ i '} "" um es in eine Variable zu bekommen. Ich fand, dass das Anfordern einfacher ist, einfache Anführungszeichen zu verwenden, und einfach eingebettete einfache Anführungszeichen zu korrigieren (daher ist es fast nicht nötig, mit Pipes / ungeraden Zeichen usw. umzugehen). Ich habe mir folgendes ausgedacht: `vquoted =" '$ (printf "$ vraw" | sed "s /" / "\" "\"' / g ")" "- probieren Sie es aus. Interessanterweise beeinflusst das Zitieren anscheinend keine Optionen: (`ls '-lt' '/'` ist ok) => sicher für alle Argumente. Stilez vor 6 Jahren 0