ubuntuusers.de

Dateinamen rekursiv auslesen / Problem mit Leerzeichen/Steuerzeichen

Status: Gelöst | Ubuntu-Version: Server 10.04 (Lucid Lynx)
Antworten |

illCP

Anmeldungsdatum:
26. Oktober 2010

Beiträge: 134

Hallo zusammen,

ich möchte eine rekursive Liste aller Dateinamen in einem Verzeichnis und in allen Unterverzeichnissen erstellen. Hierbei sollen versteckte "Punkt-Dateien" berücksichtigt werden, Verzeichnisnamen allerdings nicht. Ebenso möchte ich zu einem späteren Zeitpunkt die Dateigrößen mit ausgeben (deshalb ls -l, siehe unten).

Mein Skript sieht momentan folgendermaßen aus:

#!/bin/bash

iterate()
{
 	line=$1
	if [ ${line:0:1} == \. ]
 	then
		actual_directory=$(echo "$line" | sed 's/\./\/home\/user/; s/\(.*\):/\1/')
 	else
		line=$(echo $line | awk '{$1=$2=$3=$4=$5=""; print $0}')
		echo $actual_directory/$line
        fi
 }

ls -laRgG | grep '^[^d]' | grep '^[^insgesamt]' | while read a; do iterate "$a"; done

Ausgeführt in meinem Home-Verzeichnis ergibt dies folgende Ausgabe (Auszug):

/home/user/ .bash_history
/home/user/ .bash_logout
/home/user/ .bashrc
/home/user/ datei mit vier leerzeichen am anfang.txt
/home/user/ Eine Datei mit langem Namen und vielen Leerzeichen.txt
/home/user/ .profile
/home/user/.cache/ motd.legal-displayed
/home/user/.mc/ filepos
/home/user/.mc/ history

Fast perfekt, es ergibt sich nur ein Problem: Das "Leerzeichen", das keins ist (die "datei mit vier leerzeichen am anfang.txt" hat z.B. tatsächlich vier Leerzeichen am Anfang) - sehr schön zu erkennen, wenn man Zeile 10 im Skript folgendermaßen ändert:

line=$(echo $line | awk '{$1=$2=$3=$4=$5=""; print $0}' | sed 's/\ /[L]/' )

resultiert in (Auszug):

/home/user/[L] datei mit vier leerzeichen am anfang.txt
/home/user/[L] Eine Datei mit langem Namen und vielen Leerzeichen.txt

Hänge ich dem sed noch ein "g" an, sieht das folgendermaßen aus:

/home/user/[L][L][L][L][L]datei[L]mit[L]vier[L]leerzeichen[L]am[L]anfang.txt
/home/user/[L][L][L][L][L]Eine[L]Datei[L]mit[L]langem[L]Namen[L]und[L]vielen[L]Leerzeichen.txt

Irgendetwas passt hier nicht... Vor jeder Dateinamen stehen grundsätzlich fünf Leerzeichen, eventuelle Leerzeichen am Anfang eines Dateinamens werden ignoriert.

ls nutzt hier offenbar irgendwelche mir unbekannte Steuerzeichen zur Formatierung der Ausgabe - Tabs (\t) sind es offensichtlich nicht, zumindest springt ein

sed 's/\t/[T]/g'

nicht darauf an.

Wie ist die Ausgabe von ls formatiert? Wie separiere ich die Felder sauber und bekomme die "Trenner" weg?

Gruß

Christian

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

... zu umständlich - und wie du bereits erkennen musstest, ist die Abhängigkeit von Formatierungen durch 'ls' nicht schön.

Was du verwenden solltest:

find

siehe

 man find

... oder schau mal ins Wiki

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

theinlein schrieb:

... zu umständlich - und wie du bereits erkennen musstest, ist die Abhängigkeit von Formatierungen durch 'ls' nicht schön.

Stimme voll und ganz zu.

Was du verwenden solltest:

find

Das ganze lässt sich elegant mit einem Einzeiler erledigen, z.B.

1
$ find . -type f -exec stat -c '%n %s' {} +

Siehe man stat und man find.

Ciao

robert

illCP

(Themenstarter)

Anmeldungsdatum:
26. Oktober 2010

Beiträge: 134

Vielen Dank, so klappts:

cd $der_volle_pfad; find -type f -exec stat -c '%n %s' {} + 2>&1 | sort -g > $log_path/find_list.txt

Erlaubt ein diff zweier erzeugter Dateilisten. Und ja: Ich weiß dass z.B. rsync das automatisch überprüft, ich möchte es aber trotzdem nochmal manuell überprüfen - safety first 😉

"du" funktioniert damit entsprechend auch:

find -type f  -exec du -b -a {} +

Gruß

Christian

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

illCP schrieb:

Vielen Dank, so klappts:

Gerne.

cd $der_volle_pfad; find -type f -exec stat -c '%n %s' {} + 2>&1 | sort -g > $log_path/find_list.txt

sort -g (numerisch) ist aber m.E. nicht sinnvoll - zumal die Größe hinten steht. Nach Größe sortieren macht m.E. sowieso keinen Sinn, weil dann die diffs nicht so gut auszuwerten sind. Wenn Du nach Größe sortieren willst, empfehle ich stat -c '%20s %n' oder auch stat -c '%020s %n'.

Erlaubt ein diff zweier erzeugter Dateilisten. Und ja: Ich weiß dass z.B. rsync das automatisch überprüft, ich möchte es aber trotzdem nochmal manuell überprüfen - safety first 😉

Ciao

robert

Antworten |