Dateien mit Leerzeichen in den Namen durchlaufen? [duplizieren]

Diese Frage hat hier bereits Antworten :

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:

  1. Standardmäßig teilt die Shell die Ausgabe eines Befehls auf Leerzeichen, Tabulatoren und Zeilenumbrüche
  2. Dateinamen können Platzhalterzeichen enthalten, die würde erweitert werden
  3. 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 und read, wenn Sie find 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:

  1. Führen Sie den Befehl find aus. Holen Sie sich die Ausgabe.
  2. Teilen Sie die Ausgabe find in separate Wörter auf. Jedes Leerzeichen ist ein Worttrennzeichen.
  3. 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.

  1. Der Befehl find gibt ./foo* bar.csv zurück.
  2. Die Shell teilt diese Zeichenfolge im Leerzeichen werden zwei Wörter erzeugt: ./foo* und bar.csv.
  3. Seit ./foo* enthält ein globierendes Metazeichen und wird auf die Liste der übereinstimmenden Dateien erweitert: ./foo 1.txt und ./foo 2.txt.
  4. Daher wird die Schleife for nacheinander mit ./foo 1.txt, ./foo 2.txt und bar.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 Sie find -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 in find -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 Teil echo 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 Fragesteller read 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 "{}" \; mit time find -type f -print0 | xargs -0 -I stuff cat stuff. Die Version xargs war bei der Verarbeitung von 10000 leeren Dateien um 11 Sekunden schneller. Seien Sie vorsichtig, wenn Sie behaupten, dass das Kombinieren von find 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 Namen Hello World.csv vorhanden ist, wird file auf ./Hello und dann auf gesetzt World.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 Namen Hello World.csv, file wird auf ./Hello und dann auf World.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 zu echo "CHECKSTR `ls -l /root/somedir`".

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.