|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9837
|
Marc_BlackJack_Rintsch schrieb: Die Aussage zur rekursiven Funktion finde ich übertrieben.
Ich habe schon manchen Zauberschüler erlebt, der das auch glaubte und sich anschließend wunderte, in welche Untiefen und Probleme er bei der praktischen Umsetzung gelangte.
So eine Funktion ist nicht wirklich kompliziert und auch recht schnell geschrieben.
Aber nicht schnell getestet. Dein erster Entwurf
enthält einige offensichtliche Fehler: Die Prozedur übersieht z.B. reguläre Dateien neben Ordnern und es gibt einige Situationen, in denen sie Syntaxfehler produziert.
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
rklm schrieb: [...] Mit find: 1
2
3
4
5
6
7
8
9
10
11
12 | find Ablage -type f -name \*.flac -exec sh -c '
unset dir
for flac; do
d="$(dirname "$flac")"
if [ "$dir" != "$d" ]; then
# first one!
dir="$d"
echo "Processing: $flac ..."
fi
done' -- {} +
|
Immer noch ungetestet.
|
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4735
|
@kB Welche Dateien werden übersehen? Was für Syntaxfehler?
|
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3351
|
kB schrieb: Hor bitte auf mit diesen unfairen Angriffen, unnötigen Spitzen ...
Wer austeilt und mit entehrenden Du-Botschaften um sich wirft, sollte auch einstecken können.
Allerdings sehe ich es als Missbrauch, wenn man für Aufgaben, welche die spezifischen Fähigkeiten von find – insbesondere das rekursive Durchsuchen von Verzeichnisbäumen – nicht benötigen, dennoch find verwendet, bloß weil man eine simple Schleife vermeiden will.
Wenn das der Grund für die kommentarlose Löschung meiner angeblich "vandalistisch" eingebrachten Beispiele für 3 Arten von Verkettung von mehreren Operationen auf Funde war, warum hast Du dann nicht einfach höflich nach diesbezüglicher Änderung gefragt? Eine solche ist im Handumdrehen machbar, verlängert aber die Beispiele um 2..3 Terme, was der anderen Forderung nach Kürze allerdings entgegenlaufen würde. Wie hier im Thread – der nicht ohne Grund so länglich geworden ist – ging es um einen möglichst einfachen Rahmen zur "Ausführung komplizierterer verketteter Operationen" mit per find gefundenen Dateien. Solche Beispiele fehlen IMHO im Artikel find und der Verweis, dass man das "ganz einfach" mit einem Bash-Skript per for bewerkstelligen kann, entbehrt jeder Grundlage, wie man in hiesigem Thema sieht.
Leider verstellst Du Dich als zu doof, um diesen Punkt zu begreifen.
Und das ist kein "unfairer Angriff"?
Nochmal: Hör auf mit diesem unfairen Gebaren! (s.o.)
Ebenfalls!
|
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3351
|
kB schrieb: find . -type d -execdir find {} -maxdepth 1 -type f -name '*.flac' -print -quit \;
Wo kann ich da die eingangs erwähnte "kompliziertere Operation" unterbringen?
Diese wichtigste Frage bitte auch beantworten.
... liefert folgendes Ergebnis: […]
Eine Möglichkeit wäre: find . -type d -execdir find {} -maxdepth 1 -type f -name '*.flac' -print -quit \; | while read ; do echo ${REPLY#./} ; done
Liefert weiterhin nicht die hier benötigten relativen Pfade ab aktuellem Verzeichnis zu den Dateien.
|
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9837
|
UlfZibis schrieb: kB schrieb:
[…] >>> Wo kann ich da die eingangs erwähnte "kompliziertere Operation" unterbringen?
Diese wichtigste Frage bitte auch beantworten.
Das habe ich doch anhand der beispielhaften Bearbeitung des Dateinamens gezeigt! In der Schleife zwischen do und done kannst Du alles mit der Datei machen, deren Namen in der Schleife ja bekannt ist.
[…] Liefert weiterhin nicht die hier benötigten relativen Pfade ab aktuellem Verzeichnis zu den Dateien.
Das -print von find liefert genau das. Die Zeichen „./“ am Anfang, die Du ja weggeschnitten haben wolltest, bezeichnen genau das aktuelle Verzeichnis, ab dem gesucht und gefunden wurde. Entscheide Dich mal, ob Du das brauchst oder nicht – beides geht nicht. Wenn Du statt des dafür üblichen und funktionalen Punktes den Namen des Ordners haben willst, musst Du das selbst übersetzen. Das ist simple Verarbeitung von Zeichenketten und man kann es beispielsweise mit der Shell oder mit sed machen. Der Name des aktuellen Verzeichnisses steht in der Variablen PWD als absoluter Pfad. Das hat aber nun wirklich nichts mehr mit find, oder mit For-Schleifen oder dem Thema dieses Diskussionsfadens zu tun.
|
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4735
|
@kB Es geht nicht um ./ am Anfang oder nicht, sondern das man mit dem Ergebnis nix anfangen kann, weil da was fehlt um überhaupt an die Dateien heran zu kommen:
| $ find . -type d -execdir find {} -maxdepth 1 -type f -name '*.flac' -print -quit \; | while read ; do echo ${REPLY#./} ; done
Album2/01 titel1.flac
Album1/02-titel2.flac
|
Auch mit ./ davor ist das so nutzlos weil diese Dateien ja vom Skript aus gesehen nicht in Album2/01 titel1.flac und Album1/02-titel2.flac liegen:
| $ ls 'Album2/01 titel1.flac'
ls: cannot access 'Album2/01 titel1.flac': No such file or directory
|
Die Datei soll ja verarbeitet werden, und dazu braucht man den Pfad dort hin. Danach war gefragt. Und ich wäre auch immer noch interessiert daran welche Dateien da bei mir angeblich nicht berücksichtigt werden und welche Syntaxfehler auftreten können, und was so die erwähnten offensichtlichen Fehler sind. Ich würde gerne daraus lernen.
|
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3351
|
Marc_BlackJack_Rintsch schrieb: @kB Es geht nicht um ./ am Anfang oder nicht, sondern das man mit dem Ergebnis nix anfangen kann,
💡
|
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9837
|
Marc_BlackJack_Rintsch schrieb: @kB Es geht nicht um ./ am Anfang oder nicht, sondern das man mit dem Ergebnis nix anfangen kann, weil da was fehlt um überhaupt an die Dateien heran zu kommen […]
Danke für die Aufklärung! Damit ist das Problem leicht zu lösen: Wenn man das Arbeitsverzeichnis nicht wechseln will, muss man -exec anstatt --execdir verwenden: $find . -type d -exec find {} -maxdepth 1 -type f -name '*.flac' -print -quit \; | while read ; do ls "$REPLY" ; done
'./Various Artists/They are Playing Our Song/12 - June In January.flac'
"./Various Artists/Finnischer Tango Tule Tanssimaan/01 - Siks' oon mä suruinen.flac"
…
Statt ls kann man natürlich jedes andere Programm zu weiteren Verarbeitung verwenden.
|
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9837
|
Marc_BlackJack_Rintsch schrieb: […] Und ich wäre auch immer noch interessiert daran welche Dateien da bei mir angeblich nicht berücksichtigt werden und welche Syntaxfehler auftreten können, und was so die erwähnten offensichtlichen Fehler sind. Ich würde gerne daraus lernen.
Versteh' ich, aber in diesem Thread wäre das sachfremd und deshalb eine Themenentführung. Vielleicht an anderer Stelle, aber meine Zeit wird momentan von anderen Themen absorbiert.
|
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4735
|
@kB: Warum ist das diskutieren über eine Antwort auf die Frage des Themas hier sachfremd? In der Zeit diese Nicht-Antwort zu verfassen, hättest Du auch einfach schreiben können was die offensichtlichen Fehler sind. Erst gezeigten Code so kritisieren, dann aber nicht konkret zu sagen was die angeblich offensichtlichen Probleme sind, ist etwas unschön. Um das mal nett zu formulieren. 🫤
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17630
|
shiro schrieb: Wenn du nur die erste .flac Datei verarbeiten willst, warum machst du dann nicht folgendes?
$ # Erzeuge Spielwiese
$ mkdir -p Ablage/{Album{1,4},Interpret} Ablage/Interpret/Album{2..3}
$ touch Ablage/Album1/{123.jpg,01-titel1.flac,02-titel2.flac}
$ touch Ablage/Interpret/Album{2,3}/{123.jpg,01\ titel1.flac,02\ titel2.flac}
# ...
Sehr schön, Shiro, sehr brauchbar. Anderer Ansatz: | for d in $(find -name *.flac -exec dirname {} ";" | uniq ) ; do ls $d/*.flac | head -1 ; done
./Ablage/Album1/01-titel1.flac
./Ablage/Interpret/Album2/01 titel1.flac
./Ablage/Interpret/Album3/01 titel1.flac
|
Prämisse: Keine Zeilenumbrüche in Dateinamen. Die Lösung, die ich bevorzuge, ist, alle Leerzeichen aus Dateinamen zu eliminieren - das Minuszeichen lässt sich am besten tippen und mehrere, aufeinanderfolgende Leerzeichen, braucht man auch nicht.
|
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3351
|
user_unknown schrieb: shiro schrieb: Wenn du nur die erste .flac Datei verarbeiten willst, warum machst du dann nicht folgendes?
$ # Erzeuge Spielwiese
$ mkdir -p Ablage/{Album{1,4},Interpret} Ablage/Interpret/Album{2..3}
$ touch Ablage/Album1/{123.jpg,01-titel1.flac,02-titel2.flac}
$ touch Ablage/Interpret/Album{2,3}/{123.jpg,01\ titel1.flac,02\ titel2.flac}
# ...
Sehr schön, Shiro, sehr brauchbar.
Allerdings wäre folgendes gefordert: $ # Erzeuge Spielwiese
$ mkdir -p Ablage/{Album{1,4},Interpret} Ablage/Interpret/Album{2..3}
$ touch Ablage/{Album1,Interpret/Album2}/{123.jpg,01-titel1.flac,02-titel2.flac}
$ touch Ablage/Interpret/Album3/{123.png,01\ titel1.mp3,02\ titel2.mp3}Anderer Ansatz:
| for d in $(find -name *.flac -exec dirname {} ";" | uniq ) ; do ls $d/*.flac | head -1 ; done
|
Prämisse: Keine Zeilenumbrüche in Dateinamen.
Sehr schön kompakt.
|
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3351
|
Für einen statistischen Überblick komme ich erst mal mit folgendem gut klar: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | dirs=0;
flacdirs=0;
files01=0;
while read -r -d '' dir; do
((dirs++))
while read -r -d '' file; do
# echo "$dir";
((flacdirs++));
if [ -f "$dir"/01*.flac ]; then
((files01++));
echo 01 `ls -1 "$dir"/01*.flac`;
else
echo XX $file;
fi;
done < <(find "$dir" -maxdepth 1 -iname "*.flac" -print0 -quit | sort -z);
done < <(find Ablage -mindepth 1 -type d -print0 | sort -z)
echo Number of dirs total: $dirs;
echo Number of dirs with flac files: $flacdirs;
echo Number of 01* flac files: $files01;
|
kB schrieb: find . -type d -exec find {} -maxdepth 1 -type f -name '*.flac' -print -quit \; | while read ; do ls "$REPLY" ; done
Das taugt für obiges leider nicht, da durch -exec und die Pipe immer ein neuer Prozess gestartet wird, in dem die globalen Zählvariablen nicht zugreifbar sind. Sonst aber auch ein schöner Ansatz.
|
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9837
|
UlfZibis schrieb: Für einen statistischen Überblick […] Das taugt für obiges leider nicht […]
Vielleicht solltest Du Dir für zukünftige Supportanfragen angewöhnen, gleich zu Beginn die Aufgabe vollständig zu beschreiben, anstatt in Salamitaktik für jeden Lösungsvorschlag ein weiteres Detail als Begründung nachzuliefern, warum Du den Vorschlag leider nicht verwenden kannst. Das würde jedenfalls Frust bei Deinen Helfern vermeiden.
|