Verfügt jemand über ein Template-Shell-Skript, mit dem er etwas ls
für eine Liste von Verzeichnisnamen tun und die einzelnen durchlaufen und etwas tun kann?
Ich habe vor ls -1d */
, die Liste der Verzeichnisnamen abzurufen.
quelle
Verfügt jemand über ein Template-Shell-Skript, mit dem er etwas ls
für eine Liste von Verzeichnisnamen tun und die einzelnen durchlaufen und etwas tun kann?
Ich habe vor ls -1d */
, die Liste der Verzeichnisnamen abzurufen.
Bearbeitet, um nicht ls zu verwenden, wo ein Globus tun würde, wie @ shawn-j-goff und andere vorgeschlagen haben.
Benutze einfach eine for..do..done
Schleife:
for f in *; do
echo "File -> $f"
done
Sie können das *
mit *.txt
oder jedes andere Glob ersetzen, das eine Liste (von Dateien, Verzeichnissen oder irgendetwas anderem) zurückgibt, einen Befehl, der beispielsweise eine Liste erzeugt $(cat filelist.txt)
, oder sie tatsächlich durch eine Liste ersetzen.
Innerhalb der do
Schleife verweisen Sie einfach auf die Schleifenvariable mit dem Dollarzeichen-Präfix (so $f
im obigen Beispiel). Sie können echo
es tun oder was Sie wollen.
Um beispielsweise alle .xml
Dateien im aktuellen Verzeichnis umzubenennen, gehen Sie wie folgt vor .txt
:
for x in *.xml; do
t=$(echo $x | sed 's/\.xml$/.txt/');
mv $x $t && echo "moved $x -> $t"
done
Oder noch besser, wenn Sie Bash verwenden, können Sie Bash-Parametererweiterungen verwenden, anstatt eine Subshell zu erzeugen:
for x in *.xml; do
t=${x%.xml}.txt
mv $x $t && echo "moved $x -> $t"
done
for
Schleifen und die typische Gefahr, die Ausgabe von zu analysierenls
. @ DanielA.Weiß, Sie könnten in Betracht ziehen, diese Antwort nicht zu akzeptieren, wenn sie nicht hilfreich ist (oder möglicherweise irreführend ist), da Sie, wie Sie sagten, Verzeichnisse bearbeiten . Die Antwort von Shawn J. Goff sollte eine robustere und funktionsfähigere Lösung für Ihr Problem bieten.ls
Ausgabe nicht analysieren , Sie sollten die Ausgabe nicht in einerfor
Schleife lesen , Sie sollten$()
anstelle von `` und Use More Quotes ™ verwenden . Ich bin sicher, @CoverosGene hat es gut gemeint, aber das ist einfach schrecklich.ls
istls -1 | while read line; do stuff; done
. Zumindest wird das nicht für Leerzeichen brechen.mv -v
Ihnen brauchen nichtecho "moved $x -> $t"
Die Ausgabe von
ls
zu verwenden, um Dateinamen zu erhalten, ist eine schlechte Idee . Dies kann zu Fehlfunktionen und sogar zu gefährlichen Skripten führen. Dies liegt daran, dass ein Dateiname jedes Zeichen außer/
und dasnull
Zeichen enthalten kann undls
keines dieser Zeichen als Trennzeichen verwendet. Wenn ein Dateiname also ein Leerzeichen oder eine neue Zeile enthält, werden unerwartete Ergebnisse erzielt.Es gibt zwei sehr gute Möglichkeiten, Dateien zu durchlaufen. Hier habe ich einfach
echo
gezeigt, wie man etwas mit dem Dateinamen macht. Sie können jedoch alles verwenden.Die erste besteht darin, die nativen Globbing-Funktionen der Shell zu verwenden.
Die Shell erweitert sich
*/
in separate Argumente, die von derfor
Schleife gelesen werden. Auch wenn der Dateiname ein Leerzeichen, eine neue Zeile oder ein anderes merkwürdiges Zeichen enthält,for
wird jeder vollständige Name als atomare Einheit angezeigt . Es analysiert die Liste in keiner Weise.Wenn Sie rekursiv in Unterverzeichnissen gehen wollen, dann wird dies nicht tun , wenn Ihre Shell einige erweiterte Globbing Funktionen (zB
bash
‚sglobstar
. Wenn Ihre Shell nicht über diese Eigenschaften haben, oder wenn Sie wollen sicherstellen , dass Ihr Skript funktioniert auf einer Vielzahl von Systemen ist dann die nächste Option zu verwendenfind
.Hier
find
ruft der Befehlecho
ein Argument des Dateinamens auf und übergibt es. Dies wird einmal für jede gefundene Datei ausgeführt. Wie im vorherigen Beispiel wird keine Liste mit Dateinamen analysiert. Stattdessen wird ein Dateiformat vollständig als Argument gesendet.Die Syntax des
-exec
Arguments sieht ein bisschen komisch aus.find
Nimmt das erste Argument nach-exec
und behandelt es als auszuführendes Programm. Jedes nachfolgende Argument wird als Argument zur Übergabe an dieses Programm verwendet. Es gibt zwei spezielle Argumente,-exec
die man sehen muss. Der erste ist{}
; Dieses Argument wird durch einen Dateinamen ersetzt, den die vorherigen Teile vonfind
generieren. Die zweite ist;
, die mitteilt,find
dass dies das Ende der Liste der Argumente ist, die an das Programm übergeben werden sollen.find
benötigt dies, weil Sie mit weiteren Argumenten fortfahren können,find
die für das ausgeführte Programm bestimmt sind und nicht. Der Grund dafür\
ist, dass die Shell auch behandelt;
Insbesondere - es stellt das Ende eines Befehls dar, daher müssen wir es maskieren, damit die Shell es als Argument gibt,find
anstatt es für sich selbst zu verbrauchen. Eine andere Möglichkeit, die Shell dazu zu bringen, sie nicht speziell zu behandeln, besteht darin, sie in Anführungszeichen zu setzen: Funktioniert';'
genauso gut wie\;
für diesen Zweck.quelle
find
. Es gibt Magie, die getan werden kann, und sogar die wahrgenommenen Einschränkungen von-exec
können umgangen werden. Die-print0
Option ist auch nützlich für die Verwendung mitxargs
.Bei Dateien mit Leerzeichen müssen Sie die Variable wie folgt angeben:
Sie können auch die Umgebungsvariable IFS (Input Field Separator) ändern:
Je nachdem, was Sie gerade tun, brauchen Sie möglicherweise nicht einmal das ls:
quelle
\n
ist unzureichend. Es ist niemals eine gute Idee, das Parsen der Ausgabe von zu empfehlenls
.Wenn Sie GNU Parallel http://www.gnu.org/software/parallel/ installiert haben, können Sie dies tun:
So benennen Sie alle TXT-Dateien in XML-Dateien um:
Sehen Sie sich das Einführungsvideo für GNU Parallel an, um mehr zu erfahren: http://www.youtube.com/watch?v=OpaiGYxkSuQ
quelle
Um die Antwort von CoverosGene zu ergänzen, können Sie hier nur die Verzeichnisnamen auflisten:
quelle
Warum setzen Sie IFS nicht auf eine neue Zeile und erfassen dann die Ausgabe von
ls
in einem Array? Das Setzen von IFS auf newline sollte Probleme mit lustigen Zeichen in Dateinamen beheben. Die Verwendungls
kann nützlich sein, da eine Sortierfunktion integriert ist.(Beim Testen hatte ich Probleme, IFS auf zu setzen,
\n
aber das Setzen auf Newline Backspace funktioniert, wie an anderer Stelle hier vorgeschlagen):ZB (unter der Annahme, dass das gewünschte
ls
Suchmuster übergeben wurde$1
):Dies ist besonders praktisch , auf OS X, zum Beispiel eine Liste von Dateien nach Erstellungsdatum (alt nach neu), der zu sortier erfassen
ls
Befehl istls -t -U -r
.quelle
\n
ist unzureichend. Die einzig gültigen Lösungen verwenden eine for-Schleife mit Pfadnamenerweiterung oderfind
.So mache ich das, aber es gibt wahrscheinlich effizientere Möglichkeiten.
quelle
ls | while read i; do echo filename: $i; done