Echo Printf Formatierung

Gast #6535437
Lesenswert?

Ich habe auf einem Linux System Ext4 einen Ordner mit Dateinamen, die 
Leerzeichen enthalten. Ein kleines Shellskript, welches die Dateinamen 
einlesen und in einer Datei speichern sollte, funktioniert. Was schief 
läuft ist die Formatierung.

echo ich das Ergebnis in die Datei, wird jeder von einem Leerzeichen 
getrennte Namensbestandteil als $datei interpretiert und mit einem 
eigenen Newline versehen.

das
ist
dann
der
dateiname.txt
1
ausgabe=$(find / -name "*.txt"); for datei in $ausgabe; do filename=$(basename $datei) && echo $filename >> ./textfile.txt; done

Bei printf das gleiche in Grün, nur das dieses Mal überhaupt kein 
Newline mehr eingesetzt wird, was dann so aussieht

datei name1.txtdatei name2.txt
1
ausgabe=$(find / -name "*.txt"); for datei in $ausgabe; do filename=$(basename $datei) && printf $filename >> ./textfile.txt; done

Bei dem printf-Ansatz habe ich versucht mittels | sed s///g einfach ein 
Newline am jeweiligen Ende des Dateinamens einzusetzen. Die Substitutuon 
klappt bei anderen Zeichen, aber nicht beim Newline. Escaping 
funktioniert nicht oder ist falsch | sed -e s/.txt/.txt\\n/g (wenn ich 
es grad richtig in Erinnerung habe.)

auch ausprobiert
1
printf "%b\n" $filename
Nüschte, wieder Essig.

Gibt es überhaupt eine einfache Möglichkeit mit echo oder printf so 
etwas 👆 umzusetzen?
Gast #6535456
Lesenswert?

> Ich habe auf einem Linux System Ext4 einen Ordner mit Dateinamen, die
> Leerzeichen enthalten.

Hier damit auf, es ist dumm.

Du kannst dir jetzt irgendwas einfallen lassen um deine Probleme zu 
umgehen, aber irgendwann wird es wieder ein neues Programm geben, eine 
neues Script, irgendwas das damit wieder auf die Fresse faellt und dein 
System auf links krempelt.

Olaf
(Firma: Golden Delicious Computers) #6535472
Lesenswert?

Der Fehler passiert weder in printf noch in echo sondern hier:
1
for datei in $ausgabe

Da werden alle Leerzeichen und NewLine aus $ausgabe als Feldtrenner 
(IFS) interpretiert.

Besserer Ansatz:
1
find / -name "*.txt" | while read dateiname; do filename="$(basename "$dateiname")" && echo "$filename" >> ./textfile.txt; done

Beachte die "" bei $basename und $filename. Speziell die beim echo 
"$filename" sind ebenfalls wichtig, falls der Dateiname gleich zwei 
Leerzeichen hintereinander haben sollte. Sonst gibt der echo nur eines 
aus.
Gast #6535505
Lesenswert?

Danke Nikolaus 🙏🙏🙏

Nicht nur für die Lösung, sondern auch für den Hinweis, was eigentlich 
das Problem war. Das mit den Feldtrenner war mir nicht klar. Damit kann 
ich arbeiten bzw. mir das nochmal genauer ansehen, was es damit auf sich 
hat. Nochmals Danke!
Gast #6535668
Lesenswert?

Nikolaus S. schrieb:
> Da werden alle Leerzeichen und NewLine aus $ausgabe als Feldtrenner
> (IFS) interpretiert.

Das kann man ändern. Die Zeichen, die als Feldtrenner erkannt werden, 
stehen in der Variable IFS, also könnte man z.B. mit
1
IFS=; for datei in ...

... die Feldtrenner insgesamt deaktivieren. Man möchte das nicht unnötig 
global tun, ich halte es insgesamt nicht für die beste Lösung, aber der 
Vollständigkeit halber ...
#6535718
Lesenswert?

Tom K. schrieb:
> find -exec oder find -print0 mit xargs -0

Wollte ich auch grad schreiben. Ungefähr so:
1
find / -name '*.txt' -print0 | xargs -0 basename -a > textfile.txt

Alternativ mit einem eigenen basename-Aufruf für jede Datei statt einem 
für alle zusammen (der eine sehr lange Kommaozeile für basename ergeben 
könnte):
1
find / -name '*.txt' -exec basename {} \; > textfile.txt

Ach ja: Das *.txt sollte man wie hier gezeigt in '' setzen statt in "", 
denn sonst kommt ein ggf. unerwartetes Ergebnis raus, wenn im aktuellen 
Verzeichnis zur Zeit des Aufrufs eine Datei steht, deren Name auf .txt 
endet.
Gast #6535769
Lesenswert?

Btw, der printf von find kann "%f": "File's name with any leading 
directories removed (only the last element)."
1
find / -name "*.txt" -printf "%f\n" >textfile.txt

Der Sinn des Ganzen erschließt sich mir allerdings nicht - eine Liste 
aller .txt-Dateien ohne Pfad?!?

Btw, ein "find /" ohne Beschränkung wie z.B. "-xdev" ist eh ziemlich 
fragwürdig ...
Gast #6535825
Lesenswert?

1
find ... -exec ... {} \; >

wäre auch gegangen, bzw. ging, aber ich wollte verstehen, was bei dieser 
👆Vorgehensweise das Problem war. Auch oder gerade weil es ein sehr 
grundsätzliches Verständnisproblem der Basics zu sein schien.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren