Ordnerdurchlauf for-Schleife & find MIT Leerzeichen

R

ruediger

Grünschnabel
Hallo alle zusammen :),
ich bin ein Neuling in Sachen shellscriping und schreibe zur Zeit an einem kleinen Script und hänge seit Tagen etwas in der Luft :( .. Das Script soll einen bestimmten Ordner ($suchpfad) durchlaufen und deren Dateien und Pfade ausgeben. Leider nimmt das Script keine Ordner und Dateien die ein Leerzeichen beinhalten!
Das Problem liegt offensichtlich in der for-Schleife, die die Leerzeichen in Ordnern und Dateien falsch interpretiert, die mein Verzeichnis durchläuft. :think:

Die for-Schleife sieht wie folgt aus:
#!/bin/bash
for i in $(find $suchpfad -name "*");
do
if test -f $i
echo "$i ist eine Datei"
fi
done

Wie kann ich der for-Schleife sagen, dass Dateien & Ordner richtig an "i" geliefert werden?
Ich hoffe ihr könnt mir helfen :hilfe2:

Gruß Rüdiger
 
Hi und willkommen im Board,

ich würde das eher so machen
Code:
find $suchpfad -name $name -type f -exec ...

Also das mit den Leerzeichen mag ich mal bezweifeln da * einfach ein Wildcart ist ....
Werden überhaupt dateien ausgegeben ? Wenn nein stimmt dein Pfad nicht.

Versuch dann mal /meinPfad/*

Greetz
 
Variablen am besten in Anführungszeichen einfügen - als test "$i" - und evtl. noch mit IFS arbeiten.
 
Hi,

also zunächst mal fehlt in der Schleife zum "if" das passende "then"; nehme an/hoffe, das ist nur eine Kleinigkeit, die beim Abtippen passiert ist ...

Des weiteren führt die Schreibweise
Code:
for i in $(find $suchpfad -name "*"); do
...
dazu, dass der find-Befehl erst einmal durchläuft, und das Ergebnis davon als Ganzes in die for-Schleife substituiert wird. Spätestens jetzt hat die Shell keine Chance mehr, zu unterscheiden, ob Leerzeichen, Newlines, Tabs etc. (also der Inhalt von $IFS) als Trenner zwischen den Dateinamen oder innerhalb derselben auftreten. Du läufts also einfach mit deiner Variablen $i durch die Worte in dem Suchergebnis, und wenn drei aufeinanderfolgende eigentlich ein Dateiname sind, wen juckt das noch ...

Ein möglicher Ansatz wäre etwa, mit "while read ..." statt mit "for ..." zu arbeiten:
Code:
find "$suchpfad" -name "*" |
while read i; do
        if test -f "$i"; then 
                echo "$i ist eine Datei"
        fi
done
Das sollte auch speichereffizienter sein, weil die beiden Prozesse ("while ..." und "find") parallell arbeiten können, und nicht erst das Gesamtergebnis von "find" zwischengespeichert werden muss.

Und, wie marce schon anmerkt, Quotes um die Variablen (auch um "$suchpfad") stellen sicher, dass die Shell die Dinger nicht an den Leerzeichen aufteilt und die Komponenten dann separat weiterverwurstet.

(NB: die Option '-name "*"' kannst du auch gleich weglassen; der '*' matcht schliesslich immer.)

Wenn es wirklich nur darum geht, die regulären Dateien unterhalb von "$suchpfad" aufzulisten, ist natürlich der von foexle vorgeschlagene Weg ("find .... -type f") wesentlich besser: warum sollte man ein zusätzliches Kommando ("test") bemühen, wenn "find" das Ausfiltern sowieso mit erledigen kann.

Als Ergänzung dazu kannst du evtl. - zumindest wenn du GNU Tools verwendest - einmal "find ... -print0 ..." und "xargs -0 ..." abchecken. Damit wird als Trenner zwischen den Dateinamen ein Null-Byte verwendet, das definitiv nicht innerhalb der Namen auftreten sollte. Wenn du auf die Files aus "find ..." nur jeweils ein bestimmtes Kommando ausführen willst, ist das oft eine einfacher Weg.

Gruss,
A.
 
Als Ergänzung dazu kannst du evtl. - zumindest wenn du GNU Tools verwendest - einmal "find ... -print0 ..." und "xargs -0 ..." abchecken. Damit wird als Trenner zwischen den Dateinamen ein Null-Byte verwendet, das definitiv nicht innerhalb der Namen auftreten sollte. Wenn du auf die Files aus "find ..." nur jeweils ein bestimmtes Kommando ausführen willst, ist das oft eine einfacher Weg.
noch einfacher wäre dann, einfach -exec von find zu benutzen - da spart man sich dann sämtliche Pipes, Schleifen und andere "kruden" Dinge drumrum...
 
Hi und willkommen im Board,

danke danke :) auch nochmals allen ein fröhliches Hallo
und bereits ein herzliches Dankeschön für die vielen Antworten und Hilfestellungen

Werden überhaupt dateien ausgegeben
ja das hatte soweit alles gepasst, nur das Ordner bzw. Dateien wie beispielsweise
Order "abc d" wurde als $i=abc und $i=d ausgegeben

also zunächst mal fehlt in der Schleife zum "if" das passende "then"; nehme an/hoffe, das ist nur eine Kleinigkeit, die beim Abtippen passiert ist ...
richtig :) ich habe es beim abtippen einfach übersehen :)

find "$suchpfad" -name "*" |
while read i; do
if test -f "$i"; then
echo "$i ist eine Datei"
fi
done
vielen Dank mit der speichereffizienteren (war mir noch nicht bekannt) Variante "while" und "find" und "$i" klappt es nun wunderbar :D und die Leerzeichen werden nun auch richtig übernommen, ich denke es hat wirklich an den "" gelegen :)

vielen Dank an Alle, ihr seit klasse!

Gruß an alle
 
cron + variablen ?!?

Hallo alle zusammen,
ich hoffe ihr könnt mir nocheinmal weiterhelfen. :hilfe2:

Das Backupscript steht jetzt soweit und es funktioniert auch alles 1A :)) (wenn ich es selbst starte)
nun möchte ich es mittels cronjob 1x täglich anstoßen..
Leider klappt dies nicht :( der cron stößt es korrekt an aber leider geht dann nicht viel mehr (kein durchlauf der Ordnerstruktur usw.)
ich vermute, dass der cron die Variablen nicht ordentlich aus dem script nimmt. Gibt es da einen Trick?!? :think:

Bis jetzt habe ich dem cron die bash als Shell zugewiesen und den richtoigen Benutzer eingetragen. Im Script selbst, habe ich mit export die Variablen versehen..

wär klasse wenn jemand eine Idee hätte

Gruß ruediger
 
Zuletzt bearbeitet:
absolute Pfade verwenden und sonstige notwendige ENVs setzen, cd am Scriptanfang in richtiges Basisverzeichnis, ...
 
ahhh danke, es hat an den absoluten pfaden gehangen :)

Gruß
 

Ähnliche Themen

Verschlüsseltes Backup-Script mit rsync

find Ausgabe in "Anführungszeichen"

HandbrakeCLI Shell Skript

Wie finde ich Leerzeichen im dateinamen

bash for schleife mit if

Zurück
Oben