Ich muss ein Skript schreiben, das mein Programm mit verschiedenen Argumenten startet, aber ich bin neu in Bash. Ich beginne mein Programm mit:
./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt]
.
Hier ist der Pseudocode für das, was ich tun möchte:
for each filename in /Data do
for int i = 0, i = 3, i++
./MyProgram.exe Data/filename.txt Logs/filename_Log{i}.txt
end for
end for
Ich bin wirklich verwirrt, wie man aus dem ersten ein zweites Argument erstellt. Es sieht also wie dataABCD_Log1.txt aus und startet mein Programm.
basename -s
handelt es sich um eine nicht standardmäßige Erweiterung - ich werde meine Antwort bearbeiten, um die Standardsyntax zu verwenden.shopt -s nullglob
vor der Schleife (undshopt -u nullglob
danach, um später Probleme zu vermeiden) oder fügen Sie sieif [[ ! -e "$filename ]]; then continue; fi
am Anfang der Schleife hinzu, damit nicht vorhandene Dateien übersprungen werden.Es tut uns leid, dass Sie den Thread nekromantiert haben, aber wenn Sie Dateien durch Globbing durchlaufen, sollten Sie den Eckfall vermeiden, in dem der Glob nicht übereinstimmt (wodurch die Schleifenvariable auf die (nicht übereinstimmende) Glob-Musterzeichenfolge selbst erweitert wird).
Zum Beispiel:
Referenz: Fallstricke
quelle
shopt nullglob
ist es da! (odershopt failglob
kann auch verwendet werden, je nach gewünschtem Verhalten).dir.txt
Durch die
name=${file##*/}
Ersetzung ( Shell-Parametererweiterung ) wird der führende Pfadname bis zum letzten entfernt/
.Die
base=${name%.txt}
Substitution entfernt das Nachlaufen.txt
. Es ist etwas schwieriger, wenn die Erweiterungen variieren können.quelle
base=${name%.txt}
anstelle von seinbase=${base%.txt}
.Sie können die Option "Getrennte Null-getrennte Ausgabe" mit "Lesen" verwenden, um Verzeichnisstrukturen sicher zu durchlaufen.
Also für deinen Fall
zusätzlich
führt die while-Schleife im aktuellen Bereich des Skripts (Prozesses) aus und ermöglicht, dass die Ausgabe von find bei Bedarf zum Festlegen von Variablen verwendet wird
quelle
$'\0'
ist eine seltsame Art zu schreiben''
. Sie fehlenIFS=
und der-r
Wechsel zuread
: Ihre gelesene Anweisung sollte lauten :IFS= read -rd '' file
.$'\0'
und einige Stapelpunkte verteilt werden. Nehmen Sie die Änderungen vor, auf die Sie hingewiesen haben. Was sind die negativen Auswirkungen, wennIFS=
manecho -e "ok \nok\0" | while read -d '' line; do echo -e "$line"; done
es nicht versucht, scheint es keine zu geben. Auch -r, wie ich sehe, ist oft Standard, konnte aber kein Beispiel dafür finden, was dies verhindert.IFS=
wird benötigt, wenn ein Dateiname mit einem Leerzeichen endet: try is withtouch 'Prospero '
(beachten Sie das nachfolgende Leerzeichen). Außerdem benötigen Sie den-r
Schalter, falls ein Dateiname einen Backslash aufweist: Versuchen Sie es mittouch 'Prospero\n'
.Sieht so aus, als würden Sie versuchen, eine Windows-Datei (.exe) auszuführen. Sicherlich sollten Sie Powershell verwenden. Auf jeden Fall reicht auf einer Linux-Bash-Shell ein einfacher Einzeiler aus.
Oder in einer Bash
quelle