Kommentare
- Ich bin damit nicht einverstanden, dass dies ein Duplikat wäre. Die akzeptierte Antwort beantwortet, wie Dateinamen mit Leerzeichen durchlaufen werden. Das hat nichts mit " zu tun. Warum wird die schlechte Vorgehensweise bei der Ausgabe von ' durchlaufen? ". Ich habe diese Frage gefunden (nicht die andere), weil ich Dateinamen mit Leerzeichen durchlaufen muss, wie in: for file in $ LIST_OF_FILES; do … wobei $ LIST_OF_FILES nicht die Ausgabe von find ist; ' ist nur eine Liste von Dateinamen (durch Zeilenumbrüche getrennt).
- @CarloWood – Dateinamen können Zeilenumbrüche enthalten, daher ist Ihre Frage ziemlich eindeutig: Schleifen über Eine Liste von Dateinamen, die Leerzeichen, aber keine Zeilenumbrüche enthalten können. Ich denke, Sie ' müssen die IFS-Technik verwenden, um anzuzeigen, dass die Unterbrechung bei ' \ n '
- @ Diagonwoah, ich habe nie bemerkt, dass Dateinamen Zeilenumbrüche enthalten dürfen. Ich benutze meistens (nur) Linux / UNIX und dort sind sogar Leerzeichen selten; Ich habe sicherlich nie in meinem ganzen Leben gesehen, wie Zeilenumbrüche verwendet wurden: p. Sie könnten genauso gut verbieten, dass imho.
- @CarloWood – Dateinamen mit einer Null enden (' \ 0 ' , wie ' '). Alles andere ist akzeptabel.
- @CarloWood Sie müssen sich daran erinnern, dass die Leute zuerst abstimmen und dann lesen …
Antwort
Kurze Antwort (am nächsten an Ihrer Antwort, behandelt jedoch Leerzeichen)
OIFS="$IFS" IFS=$"\n" for file in `find . -type f -name "*.csv"` do echo "file = $file" diff "$file" "/some/other/path/$file" read line done IFS="$OIFS"
Bessere Antwort (behandelt auch Platzhalter und Zeilenumbrüche in Dateinamen)
find . -type f -name "*.csv" -print0 | while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty done
Beste Antwort (basierend auf Gilles “ Antwort )
find . -type f -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty " exec-sh {} ";"
Oder noch besser, um zu vermeiden, dass eine sh
pro Datei:
find . -type f -name "*.csv" -exec sh -c " for file do echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty done " exec-sh {} +
Lange Antwort
Sie haben drei Probleme:
- Standardmäßig teilt die Shell die Ausgabe eines Befehls auf Leerzeichen, Tabulatoren und Zeilenumbrüche
- Dateinamen können Platzhalterzeichen enthalten, die würde erweitert werden
- Was ist, wenn es ein Verzeichnis gibt, dessen Name auf
*.csv
endet?
1. Nur in Zeilenumbrüchen aufteilen
Um herauszufinden, worauf file
gesetzt werden soll, muss die Shell die Ausgabe übernehmen von find
und interpretieren Sie es irgendwie, sonst wäre file
nur die gesamte Ausgabe von find
Die Shell liest die Variable IFS
, die standardmäßig auf <space><tab><newline>
gesetzt ist.
Dann wird jedes Zeichen in der Ausgabe von find
betrachtet. Sobald ein Zeichen „s in IFS
angezeigt wird, wird das Ende des Dateinamens markiert, sodass file
festgelegt wird zu den Zeichen, die es bisher gesehen hat, und führt die Schleife aus. Dann beginnt es dort, wo es aufgehört hat, um den nächsten Dateinamen zu erhalten, und führt die nächste Schleife usw. aus, bis das Ende der Ausgabe erreicht ist.
Dies geschieht also effektiv:
for file in "zquery" "-" "abc" ...
Um anzugeben, dass die Eingabe nur in Zeilenumbrüchen aufgeteilt werden soll, müssen Sie
IFS=$"\n"
vor Ihrem Befehl for ... find
.
Damit wird IFS
auf a gesetzt einzelne Zeilenumbrüche, daher werden nur Zeilenumbrüche und keine Leerzeichen und Tabulatoren aufgeteilt.
Wenn Sie sh
oder dash
Anstelle von ksh93
, bash
oder zsh
müssen Sie IFS=$"\n"
sieht stattdessen so aus:
IFS=" "
Das ist wahrscheinlich genug Um Ihr Skript zum Laufen zu bringen, aber wenn Sie daran interessiert sind, einige andere Eckfälle richtig zu behandeln, lesen Sie weiter …
2. Erweitern von $file
ohne Platzhalter
Innerhalb der Schleife, in der Sie
Die Shell versucht, $file
(wieder!) zu erweitern.
Sie könnte Leerzeichen enthalten, aber da wir bereits IFS
oben, das wird hier kein Problem sein.
Es kann aber auch Platzhalterzeichen wie *
oder ?
enthalten, was zu unvorhersehbarem Verhalten führen würde. (Vielen Dank an Gilles für diesen Hinweis.)
Um die Shell anzuweisen, keine Platzhalterzeichen zu erweitern, setzen Sie die Variable in doppelte Anführungszeichen, z. B.
diff "$file" "/some/other/path/$file"
Das gleiche Problem könnte uns auch in
for file in `find . -name "*.csv"`
beißen, wenn Sie beispielsweise diese drei Dateien hätten
file1.csv file2.csv *.csv
(sehr unwahrscheinlich, aber immer noch möglich)
Es wäre, als hätten Sie
for file in file1.csv file2.csv *.csv
die auf
for file in file1.csv file2.csv *.csv file1.csv file2.csv
erweitert wird und file1.csv
und file2.csv
zweimal verarbeitet werden.
Stattdessen müssen wir
find . -name "*.csv" -print | while IFS= read -r file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty done
read
ausführen Liest Zeilen von der Standardeingabe, teilt die Zeile gemäß IFS
in Wörter auf und speichert sie in den von Ihnen angegebenen Variablennamen.
Hier erzählen wir es Die Zeile nicht in Wörter aufteilen und in $file
speichern.
Beachten Sie auch, dass wurde in read line </dev/tty
geändert.
Dies liegt daran, dass innerhalb der Schleife die Standardeingabe von find
über die Pipeline.
Wenn wir nur read
ausführen würden, würde ein Teil oder der gesamte Dateiname verbraucht und einige Dateien würden übersprungen
/dev/tty
ist das Terminal, von dem aus der Benutzer das Skript ausführt. Beachten Sie, dass dies einen Fehler verursacht, wenn das Skript über cron ausgeführt wird. Ich gehe jedoch davon aus, dass dies in diesem Fall nicht wichtig ist.
Was ist dann, wenn ein Dateiname Zeilenumbrüche enthält?
Wir können damit umgehen, indem wir -print
in -print0
ändern und read -d ""
am Ende von a verwenden Pipeline:
find . -name "*.csv" -print0 | while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read char </dev/tty done
Dadurch setzt find
am Ende jedes Dateinamens ein Null-Byte. Null-Bytes sind die einzigen Zeichen, die in Dateinamen nicht zulässig sind. Daher sollten alle möglichen Dateinamen behandelt werden, egal wie seltsam sie auch sein mögen.
Um den Dateinamen auf der anderen Seite abzurufen, verwenden wir IFS= read -r -d ""
.
Wo wir oben read
verwendet haben, haben wir den Standardzeilentrenner von newline verwendet, jetzt jedoch find
verwendet null als Zeilenbegrenzer. In bash
können Sie ein NUL-Zeichen in einem Argument nicht an einen Befehl übergeben (auch nicht an eingebaute), aber bash
versteht -d ""
bedeutet NUL begrenzt . Daher verwenden wir -d ""
, um read
Verwenden Sie denselben Zeilenbegrenzer wie find
. Beachten Sie, dass -d $"\0"
übrigens auch funktioniert, da bash
unterstützt keine NUL-Bytes und behandelt sie als leere Zeichenfolge.
Um korrekt zu sein, fügen wir auch -r
hinzu, das besagt, dass Backslashes nicht verarbeitet werden Dateinamen speziell. Ohne -r
werden beispielsweise \<newline>
entfernt und \n
wird in n
.
Eine portablere Schreibweise, für die nicht bash
oder oder Erinnern an alle oben genannten Regeln für Null-Bytes (erneut dank Gilles):
find . -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read char </dev/tty " exec-sh {} ";"
* 3. Überspringen von Verzeichnissen, deren Namen enden mit .csv
find . -name "*.csv"
stimmen auch mit Verzeichnissen überein, die something.csv
.
Um dies zu vermeiden, fügen Sie -type f
zum Befehl find
hinzu.
find . -type f -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty " exec-sh {} ";"
Wie zeigt glenn jackman in beiden Beispielen die Befehle aus, die für jede Datei ausgeführt werden müssen Wenn Sie also Variablen in der Schleife ändern, werden diese vergessen.
Wenn Sie Variablen festlegen müssen und diese noch festlegen müssen Am Ende der Schleife können Sie sie neu schreiben, um die Prozessersetzung wie folgt zu verwenden:
i=0 while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty i=$((i+1)) done < <(find . -type f -name "*.csv" -print0) echo "$i files processed"
Beachten Sie dies, wenn Sie versuchen, diese in der Befehlszeile zu kopieren und einzufügen , read line
verwendet die echo "$i files processed"
, sodass dieser Befehl nicht ausgeführt wird.
Um dies zu vermeiden, müssen Sie dies tun könnte read line </dev/tty
entfernen und das Ergebnis an einen Pager wie less
senden.
HINWEISE
Ich habe die Semikolons (;
) in der entfernt Schleife. Sie können sie zurücksetzen, wenn Sie möchten, aber sie werden nicht benötigt.
Heutzutage ist $(command)
häufiger als `command`
. Dies liegt hauptsächlich daran, dass es einfacher ist, $(command1 $(command2))
als `command1 \`command2\``
zu schreiben.
read char
liest ein Zeichen nicht wirklich.Es liest eine ganze Zeile, also habe ich sie in read line
geändert.
Kommentare
-
while
in einer Pipeline kann Probleme mit der erstellten Subshell verursachen (Variablen im Schleifenblock sind beispielsweise nach Abschluss des Befehls nicht sichtbar). Mit bash würde ich die Umleitung von Eingaben und die Prozessersetzung verwenden:while read -r -d $'\0' file; do ...; done < <(find ... -print0)
- Sicher, oder mit einem Heredoc:
while read; do; done <<EOF "$(find)" EOF
. Nicht so einfach zu lesen. - @glenn jackman: Ich habe gerade versucht, weitere Erklärungen hinzuzufügen. Habe ich es gerade besser oder schlechter gemacht?
- Sie benötigen ' nicht
IFS, -print0, while
undread
, wenn Siefind
vollständig verarbeiten, wie unten in meiner Lösung gezeigt. - Ihre erste Lösung kann mit jedem Zeichen außer Zeilenumbruch umgehen Wenn Sie das Globbing auch mit
set -f
deaktivieren.
Antwort
Dieses Skript schlägt fehl, wenn ein Dateiname Leerzeichen oder Shell-Globbing-Zeichen enthält \[?*
. Der Befehl find
gibt einen Dateinamen pro Zeile aus. Anschließend wird die Befehlssubstitution `find …`
von der Shell wie folgt ausgewertet:
- Führen Sie den Befehl
find
aus. Holen Sie sich die Ausgabe. - Teilen Sie die Ausgabe
find
in separate Wörter auf. Jedes Leerzeichen ist ein Worttrennzeichen. - Wenn es sich bei jedem Wort um ein Globbing-Muster handelt, erweitern Sie es auf die Liste der übereinstimmenden Dateien.
Beispiel: Angenommen, das aktuelle Verzeichnis enthält drei Dateien mit den Namen `foo* bar.csv
, foo 1.txt
und foo 2.txt
.
- Der Befehl
find
gibt./foo* bar.csv
zurück. - Die Shell teilt diese Zeichenfolge im Leerzeichen werden zwei Wörter erzeugt:
./foo*
undbar.csv
. - Seit
./foo*
enthält ein globierendes Metazeichen und wird auf die Liste der übereinstimmenden Dateien erweitert:./foo 1.txt
und./foo 2.txt
. - Daher wird die Schleife
for
nacheinander mit./foo 1.txt
,./foo 2.txt
undbar.csv
.
Sie können die meisten Probleme in dieser Phase vermeiden, indem Sie die Wortteilung und das Umdrehen abschwächen Globbing ab. Um die Wortteilung zu verringern, setzen Sie die Variable IFS
auf ein einzelnes Zeilenumbruchzeichen. Auf diese Weise wird die Ausgabe von find
nur bei Zeilenumbrüchen aufgeteilt und Leerzeichen bleiben erhalten. Führen Sie set -f
aus, um das Globbing zu deaktivieren. Dann funktioniert dieser Teil des Codes, solange kein Dateiname ein Zeilenumbruchzeichen enthält.
IFS=" " set -f for file in $(find . -name "*.csv"); do …
(Dies ist nicht Teil Ihres Problems, aber ich empfehlen die Verwendung von $(…)
über `…`
. Sie haben dieselbe Bedeutung, aber die Backquote-Version hat seltsame Anführungsregeln.)
Es gibt unten ein weiteres Problem: diff $file /some/other/path/$file
sollte
diff "$file" "/some/other/path/$file"
sein. Andernfalls ist der Wert von $file
wird in Wörter aufgeteilt und die Wörter werden wie beim obigen Befehlsersatz als Glob-Muster behandelt. Wenn Sie sich an eine Sache bei der Shell-Programmierung erinnern müssen, denken Sie daran: Verwenden Sie immer doppelte Anführungszeichen um Variablenerweiterungen ($foo
) und Befehlsersetzungen ( $(bar)
) , es sei denn, Sie wissen, dass Sie teilen möchten. (Oben wussten wir, dass wir die Ausgabe von find
in Zeilen aufteilen wollten.)
Eine zuverlässige Methode zum Aufrufen von find
weist es an, für jede gefundene Datei einen Befehl auszuführen:
find . -name "*.csv" -exec sh -c " echo "$0" diff "$0" "/some/other/path/$0" " {} ";"
In diesem Fall besteht ein anderer Ansatz darin, die beiden Verzeichnisse zu vergleichen, obwohl dies erforderlich ist Schließen Sie explizit alle „langweiligen“ Dateien aus.
diff -r -x "*.txt" -x "*.ods" -x "*.pdf" … . /some/other/path
Kommentare
- I ' hatte Platzhalter als weiteren Grund für ein korrektes Zitat vergessen. Vielen Dank! 🙂
- anstelle von
find -exec sh -c 'cmd 1; cmd 2' ";"
sollten Siefind -exec cmd 1 {} ";" -exec cmd 2 {} ";"
verwenden, da die Shell die Parameter maskieren muss. aber find nicht ' t. In diesem speziellen Fall muss das Echo " $ 0 " ' nicht a sein Als Teil des Skripts fügen Sie einfach -print nach';'
an. Sie haben ' keine Frage hinzugefügt, um fortzufahren, aber selbst das kann durch Finden erfolgen, wie unten in meiner Soulution gezeigt. 😉 - @userunknown: Die Verwendung von
{}
als Teilzeichenfolge eines Parameters infind -exec
ist nicht portierbar. ' ist der Grund, warum die Shell benötigt wird.Ich verstehe ' nicht, was Sie unter „Die Shell muss die Parameter maskieren“ verstehen. Wenn es ' um das Zitieren geht, wird meine Lösung richtig zitiert. Sie ' haben Recht, dass der Teilecho
stattdessen von-print
ausgeführt werden könnte.-okdir
ist eine relativ neue GNU-Sucherweiterung. ' ist nicht überall verfügbar. ' hat das Warten auf den Vorgang nicht berücksichtigt, da ich der Meinung bin, dass eine extrem schlechte Benutzeroberfläche und der Fragestellerread
problemlos in das Shell-Snippet einfügen können, wenn er will. - Zitieren ist eine Form der Maskierung, nicht wahr '? Ich verstehe ' Ihre Bemerkung darüber, was tragbar ist und was nicht. Ihr Beispiel (2. von unten) verwendet -exec, um
sh
aufzurufen, und verwendet{}
– also wo ist mein Beispiel (neben -okdir) weniger tragbar?find . -name "*.csv" -exec diff {} /some/other/path/{} ";" -print
- „Masking“ ist keine ' gebräuchliche Terminologie in der Shell-Literatur, daher ' muss erklären, was du meinst, wenn du verstanden werden willst. In meinem Beispiel wird
{}
nur einmal und in einem separaten Argument verwendet. Andere Fälle (zweimal oder als Teilzeichenfolge verwendet) sind nicht tragbar. „Portable“ bedeutet, dass ' auf allen Unix-Systemen funktioniert. Eine gute Richtlinie ist die POSIX / Single Unix-Spezifikation .
Antwort
Ich bin überrascht, dass readarray
nicht erwähnt wird. Dies ist in Kombination mit <<<
operator:
$ touch oneword "two words" $ readarray -t files <<<"$(ls)" $ for file in "${files[@]}"; do echo "|$file|"; done |oneword| |two words|
Mit dem Konstrukt <<<"$expansion"
können Sie auch Variablen, die Zeilenumbrüche enthalten, in Arrays aufteilen, z :
$ string=$(dmesg) $ readarray -t lines <<<"$string" $ echo "${lines[0]}" [ 0.000000] Initializing cgroup subsys cpuset
readarray
ist seit Jahren in Bash, daher sollte dies wahrscheinlich der kanonische Weg sein Dies in Bash.
Antwort
Afaik find hat alles, was Sie brauchen.
find . -okdir diff {} /some/other/path/{} ";"
find kümmert sich darum, die Programme sicher aufzurufen. -okdir fordert Sie vor dem Diff auf (sind Sie sicher, ja / nein).
Keine Shell beteiligt, kein Globbing, Joker, pi, pa, po.
Als Nebenbemerkung: Wenn Sie find mit for / while / do / xargs kombinieren, ist in den meisten Fällen y Du machst es falsch. 🙂
Kommentare
- Danke für die Antwort. Warum machen Sie es falsch, wenn Sie find mit for / while / do / xargs kombinieren?
- Find iteriert bereits über eine Teilmenge von Dateien. Die meisten Leute, die mit Fragen auftauchen, können einfach eine der Aktionen (-ok (dir) -exec (dir), -delete) in Kombination mit "; oder + (später für parallelen Aufruf). Der Hauptgrund dafür ist, dass Sie ' nicht mit Dateiparametern herumspielen müssen, um sie für die Shell zu maskieren. Nicht so wichtig: Sie müssen ' nicht ständig neue Prozesse durchführen, weniger Speicher, mehr Geschwindigkeit. kürzeres Programm.
- Nicht hier, um Ihren Geist zu zerstören, aber vergleichen Sie:
time find -type f -exec cat "{}" \;
mittime find -type f -print0 | xargs -0 -I stuff cat stuff
. Die Versionxargs
war bei der Verarbeitung von 10000 leeren Dateien um 11 Sekunden schneller. Seien Sie vorsichtig, wenn Sie behaupten, dass das Kombinieren vonfind
mit anderen Dienstprogrammen in den meisten Fällen falsch ist.-print0
und-0
dienen dazu, Leerzeichen in den Dateinamen zu behandeln, indem ein Null-Byte als Elementtrennzeichen anstelle eines Leerzeichens verwendet wird. - @JonathanKomar: Ihr find / exec-Kommando dauerte auf meinem System 11,7 s mit 10.000 Dateien, die xargs-Version 9.7 s,
time find -type f -exec cat {} +
, wie in meinem vorherigen Kommentar vorgeschlagen, dauerte 0,1 s. Beachten Sie den subtilen Unterschied zwischen ", es ist falsch " und " Sie ' macht es falsch ", besonders wenn es mit einem Smilie dekoriert ist. Haben Sie es zum Beispiel falsch gemacht? 😉 Übrigens sind Leerzeichen im Dateinamen für den obigen Befehl kein Problem und finden im Allgemeinen. Frachtkult-Programmierer? Übrigens ist das Kombinieren von Find mit anderen Tools in Ordnung, nur Xargs ist meistens überflüssig. - @userunknown Ich erklärte, wie mein Code mit Räumen für die Nachwelt umgeht (Bildung zukünftiger Zuschauer) und war Dies bedeutet nicht, dass Ihr Code dies nicht tut. Die
+
für parallele Anrufe ist, wie Sie erwähnt haben, sehr schnell. Ich würde nicht sagen, Frachtkult-Programmierer, weil diese Fähigkeit,xargs
auf diese Weise zu verwenden, bei zahlreichen Gelegenheiten nützlich ist. Ich stimme der Unix-Philosophie eher zu: Machen Sie eine Sache und machen Sie es gut (verwenden Sie Programme separat oder in Kombination, um einen Job zu erledigen).find
geht dort eine feine Linie.
Antwort
Durchlaufen Sie alle Dateien ( beliebige Sonderzeichen enthalten) mit dem völlig sicherer Fund (Dokumentation finden Sie unter dem Link):
exec 9< <( find "$absolute_dir_path" -type f -print0 ) while IFS= read -r -d "" -u 9 do file_path="$(readlink -fn -- "$REPLY"; echo x)" file_path="${file_path%x}" echo "START${file_path}END" done
Kommentare
- Vielen Dank, dass Sie
-d ''
erwähnt haben. Ich habe ' nicht bemerkt, dass$'\0'
dasselbe ist wie''
, aber es scheint Sein. Gute Lösung auch. - Ich mag die Entkopplung von find und while, danke.
Answer
Ich bin überrascht, dass hier noch niemand die offensichtliche zsh
-Lösung erwähnt hat:
for file (**/*.csv(ND.)) { do-something-with $file }
((D)
, um auch versteckte Dateien einzuschließen, (N)
, um den Fehler zu vermeiden, wenn keine Übereinstimmung vorliegt, (.)
, um sich auf reguläre Dateien zu beschränken.)
bash4.3
und höher unterstützt dies jetzt auch teilweise:
shopt -s globstar nullglob dotglob for file in **/*.csv; do [ -f "$file" ] || continue [ -L "$file" ] && continue do-something-with "$file" done
Antwort
Dateinamen mit Leerzeichen sehen wie mehrere Namen in der Befehlszeile aus, wenn sie “ Wenn Ihre Datei den Namen „Hello World.txt“ trägt, wird die Diff-Zeile erweitert zu:
diff Hello World.txt /some/other/path/Hello World.txt
, was wie vier Dateinamen aussieht Anführungszeichen um die Argumente:
diff "$file" "/some/other/path/$file"
Kommentare
- Dies hilft, aber es tut nicht ' Löse mein Problem nicht. Ich sehe immer noch Fälle, in denen die Datei in mehrere Token aufgeteilt wird.
- Diese Antwort ist irreführend. Das Problem ist der Befehl
for file in `find . -name "*.csv"`
. Wenn eine Datei mit dem NamenHello World.csv
vorhanden ist, wirdfile
auf./Hello
und dann auf gesetztWorld.csv
. Das Zitieren von$file
hilft ' nicht.
Antwort
Doppelte Anführungszeichen sind Ihr Freund.
diff "$file" "/some/other/path/$file"
Andernfalls wird der Inhalt der Variablen in Wörter aufgeteilt.
Kommentare
- Dies ist irreführend. Das Problem ist der Befehl
for file in `find . -name "*.csv"`
. Wenn eine Datei mit dem NamenHello World.csv
,file
wird auf./Hello
und dann aufWorld.csv
. Das Zitieren von$file
hilft ' nicht.
Antwort
Mit bash4 können Sie auch die integrierte Mapfile-Funktion verwenden, um ein Array mit den einzelnen Zeilen festzulegen und dieses Array zu iterieren.
$ tree . ├── a │ ├── a 1 │ └── a 2 ├── b │ ├── b 1 │ └── b 2 └── c ├── c 1 └── c 2 3 directories, 6 files $ mapfile -t files < <(find -type f) $ for file in "${files[@]}"; do > echo "file: $file" > done file: ./a/a 2 file: ./a/a 1 file: ./b/b 2 file: ./b/b 1 file: ./c/c 2 file: ./c/c 1
Antwort
Die Leerzeichen in den Werten können vermieden werden, indem das Schleifenkonstrukt so einfach wie möglich ist.
for CHECK_STR in `ls -l /root/somedir` do echo "CHECKSTR $CHECK_STR" done
ls -l root / somedir c Erhält meine Datei mit Leerzeichen
Ausgabe über meiner Datei mit Leerzeichen
, um diese Ausgabe zu vermeiden. Einfache Lösung (doppelte Anführungszeichen beachten)
for CHECK_STR in "`ls -l /root/somedir`" do echo "CHECKSTR $CHECK_STR" done
gibt meine Datei mit Leerzeichen aus
versucht auf Bash
Kommentare
- „Durchlaufen von Dateien ”- das sagt die Frage. Ihre Lösung gibt die gesamte
ls -l
Ausgabe sofort aus. Es ist effektiv äquivalent zuecho "CHECKSTR `ls -l /root/somedir`"
.