das Durchlaufen von ' ls ' führt zu einem Bash-Shell-Skript
Hat jemand ein Template-Shell-Skript, um etwas mit ls
für eine Liste von Verzeichnisnamen zu tun und jede zu durchlaufen und etwas zu tun?
Ich plane ls -1d */
, um die Liste der Verzeichnisnamen abzurufen.
9 answers
Bearbeitet, um ls nicht zu verwenden, wo ein glob 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 *
durch *.txt
oder einen anderen Glob ersetzen, der eine Liste (von Dateien, Verzeichnissen oder irgendetwas anderem) zurückgibt, einen Befehl, der eine Liste generiert, z. B. $(cat filelist.txt)
oder tatsächlich durch eine Liste ersetzen.
Innerhalb der Schleife do
beziehen Sie sich nur auf die Schleifenvariable mit dem Dollarzeichen-Präfix (also $f
oben Beispiel). Sie können es echo
oder etwas anderes tun, was Sie wollen.
Zum Beispiel, um alle .xml
Dateien im aktuellen Verzeichnis in .txt
umzubenennen:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2015-05-08 00:00:06
Die Verwendung der Ausgabe von ls
zum Abrufen von Dateinamen ist eine schlechte Idee. Es kann zu Fehlfunktionen und sogar gefährlichen Skripten führen. Dies ist, weil ein Dateiname kann beliebige Zeichen enthalten, außer /
und null
Charakter, und ls
nicht verwenden Sie eines dieser Zeichen als Begrenzungszeichen, so dass, wenn ein Dateiname ein Leerzeichen oder ein Zeilenumbruch ist, die Sie wird unerwartete Ergebnisse erhalten.
Es gibt zwei sehr gute Möglichkeiten, Dateien zu durchlaufen. Hier habe ich einfach echo
verwendet, um dies zu demonstrieren etwas mit dem Dateinamen; Sie können jedoch alles verwenden.
Die erste besteht darin, die nativen Globbing-Funktionen der Shell zu verwenden.
for dir in */; do
echo "$dir"
done
Die Shell erweitert */
in separate Argumente, die die Schleife for
liest; Selbst wenn es ein Leerzeichen, einen Zeilenumbruch oder ein anderes seltsames Zeichen im Dateinamen gibt, sieht for
jeden vollständigen Namen als atomare Einheit; Es analysiert die Liste in keiner Weise.
Wenn Sie rekursiv in Unterverzeichnisse gehen wollen, dann wird dies nicht tun, wenn Ihre shell hat einige erweiterte globbing-Funktionen (wie bash
's globstar
. Wenn Ihre Shell nicht über diese Funktionen verfügt oder Sie sicherstellen möchten, dass Ihr Skript auf einer Vielzahl von Systemen funktioniert, verwenden Sie als Nächstes find
.
find . -type d -exec echo '{}' \;
Hier ruft der Befehl find
echo
auf und übergibt ihm ein Argument des Dateinamens. Es tut dies einmal für jede Datei, die es findet. Wie im vorherigen Beispiel gibt es kein Parsen einer Liste von Dateinamen; Stattdessen wird ein Dateiname vollständig als Argument.
Die Syntax des Arguments -exec
sieht ein wenig komisch aus. find
nimmt das erste Argument nach -exec
und behandelt es als das auszuführende Programm, und jedes nachfolgende Argument wird als Argument an dieses Programm übergeben. Es gibt zwei spezielle Argumente, die -exec
sehen muss. Der erste ist {}
; Dieses Argument wird durch einen Dateinamen ersetzt, den die vorherigen Teile von find
erzeugen. Der zweite ist ;
, wodurch find
wissen kann, dass dies das Ende der Liste von argumente, die an das Programm übergeben werden sollen; find
benötigt dies, da Sie mit weiteren Argumenten fortfahren können, die für find
und nicht für das exec ' d-Programm bestimmt sind. Der Grund für das \
ist, dass die Shell auch ;
speziell behandelt - es stellt das Ende eines Befehls dar, also müssen wir es entkommen, damit die Shell es als Argument für find
gibt, anstatt es für sich selbst zu konsumieren; Eine andere Möglichkeit, die Shell dazu zu bringen, es nicht speziell zu behandeln, besteht darin, es in Anführungszeichen zu setzen: ';'
funktioniert genauso sowie \;
für diesen Zweck.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2014-07-23 13:00:46
Für Dateien mit Leerzeichen müssen Sie sicherstellen, dass die Variable wie folgt zitiert wird:
for i in $(ls); do echo "$i"; done;
Oder Sie können die Umgebungsvariable Input Field Separator (IFS) ändern:
IFS=$'\n';for file in $(ls); do echo $i; done
Schließlich benötigen Sie je nachdem, was Sie tun, möglicherweise nicht einmal die ls:
for i in *; do echo "$i"; done;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2009-08-28 17:26:27
Wenn Sie GNU Parallel haben http://www.gnu.org/software/parallel/ installiert Sie können dies tun:
ls | parallel echo {} is in this dir
Um alle umzubenennen .txt zu .xml:
ls *.txt | parallel mv {} {.}.xml
Sehen Sie sich das Intro-Video für GNU Parallel an, um mehr zu erfahren: http://www.youtube.com/watch?v=OpaiGYxkSuQ
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2012-04-30 00:49:30
Nur um die Antwort von CoverosGene hinzuzufügen, hier ist eine Möglichkeit, nur die Verzeichnisnamen aufzulisten:
for f in */; do
echo "Directory -> $f"
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2015-02-11 14:36:01
Warum nicht IFS auf eine neue Zeile setzen und dann die Ausgabe von ls
in einem Array erfassen? Wenn Sie IFS auf Newline setzen, sollten Probleme mit lustigen Zeichen in Dateinamen behoben werden; Die Verwendung von ls
kann hilfreich sein, da es über eine integrierte Sortierfunktion verfügt.
(Beim Testen hatte ich Probleme, IFS auf \n
zu setzen, aber das Setzen auf Newline Backspace funktioniert, wie an anderer Stelle hier vorgeschlagen):
ZB (vorausgesetzt, das gewünschte ls
Suchmuster wurde übergeben $1
):
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
FILES=($(/bin/ls "$1"))
for AFILE in ${FILES[@]}
do
... do something with a file ...
done
IFS=$SAVEIFS
Dies ist besonders praktisch unter OS X, um beispielsweise eine Liste von Dateien zu erfassen, die nach Erstellungsdatum sortiert sind (älteste bis neueste), lautet der Befehl ls
ls -t -U -r
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2012-10-22 01:09:13
While Schleife mit ls Befehl in einer Befehlszeile
ls | while read filename;do echo "file name is $filename"; done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2020-10-06 22:05:14
Es ist präfektlich in Ordnung:
#!/bin/sh
for i in `ls`
do
echo `ls -l $i`
done
Hier ist die Ausgabe:
root@online:/usr/local/httpd/bin # more ~root/rm-in-ls.sh
#!/bin/sh
for i in `ls`
do
echo `ls -l $i`
done
root@online:/usr/local/httpd/bin # /root/rm-in-ls.sh
-rwxr-xr-x 1 root wheel 82516 Jul 3 04:52 ab
-rwxr-xr-x 1 root 40 3431 Jul 3 04:35 apachectl
-rwxr-xr-x 1 root 40 23881 Jul 3 04:35 apxs
-rwxr-xr-x 1 root wheel 21456 Jul 3 04:52 checkgid
-rwxr-xr-x 1 root 40 8931 Jul 3 04:35 dbmmanage
root@online:/usr/local/httpd/bin #
Verpasst ! Richtig !!!
- HEADS UP !!!
Das ist nicht "'" in 'ls' !!! Das ist " ` " in `ls`. Der akute nicht apostroph. Es gibt einen Unterschied zwischen ' und `. Ich verbrachte eine Woche damit, um herauszufinden, wann ich auf dem College war (1990).
Dies ist "`", die Taste mit ~ Tilde + shift+~, sie heißt akut.wiki
Wenn Sie es nicht erhalten haben, kopieren und fügen Sie das Skript ein und führen Sie es aus.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2020-07-14 23:30:01
So mache ich es, aber es gibt wahrscheinlich effizientere Wege.
ls > filelist.txt
while read filename; do echo filename: "$filename"; done < filelist.txt
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2009-08-28 17:28:24