staging.inyokaproject.org

Fehlende *.sfv Dateien suchen

Status: Gelöst | Ubuntu-Version: Kubuntu 13.04 (Raring Ringtail)
Antworten |

synapsen.stau

Avatar von synapsen.stau

Anmeldungsdatum:
27. Mai 2007

Beiträge: 266

Moin an die Herren und Damen der Shell Script Profis,

ich würde gerne meine Musiksammlung nach fehlender "*.sfv" Datei durschuen lassen. Da diese aber leider etwas umfangreicher ist, würde ich das ungerne von Hand machen und da dachte ich mir, das sowas doch bestimmt die Shell kann. Dabei ist es egal ob es ein "ganzes" Script wird oder aber es ein einzeiler schafft.

Ich stelle mir das so vor: Beim Aufruf gebe ich das rekursiv zu durchsuchende Verzeichnis an (z.B. ~/Musik/) und am Ende habe ich dann eine Liste der absoluten Verzeichnissepfade, die keine *.sfv Datei beinhalten. Am besten natürlich in einer txt Datei, wobei ich die Umleitung von stout in ein Datei auch noch selber schaffen würde.

Ich habe heut morgen schon versucht mir selber zu helfen, finde aber keinen richtigen Ansatzpunkt.

Maik

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Ich gehe mal davon aus, dass Du eine *.sfv - Datei pro Verzeichnis meinst, und nicht pro Musikdatei. (das hast Du nämlich nicht genau dazu gesagt)

Als erstes musst Du wahrscheinlich mit find die Verzeichnisse suchen gehen, und dann in jedem Verzeichnis nachgucken, wie viele *.sfv - Dateien er dort findet. Das habe ich hier mal mit einer Untershell gemacht, die die Dateinamen ggf. in ein Array expandiert, und dann guckt, ob das Array leer ist:

find ~/Musik -type d -exec bash -c 'shopt -s nullglob; f=( "$0"/*.sfv ); if [ "${#f[@]}" = 0 ]; then echo "$0"; fi' {} \;

LG,

track

synapsen.stau

(Themenstarter)
Avatar von synapsen.stau

Anmeldungsdatum:
27. Mai 2007

Beiträge: 266

Ich danke DIR. Genau sowas hab ich gesucht, ☺

Funktioniert wunderbar.....

Natürlich meinte ich 1 x *.sfv pro Verzeichnis.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

track schrieb:

find ~/Musik -type d -exec bash -c 'shopt -s nullglob; f=( "$0"/*.sfv ); if [ "${#f[@]}" = 0 ]; then echo "$0"; fi' {} \;

Sorry, aber ich möchte noch ein bisschen pingeln. ☺ Folgende Dinge gefallen mir da dieser Lösung nicht so gut:

  1. Es wird eine Shell pro Verzeichnis erzeugt.

  2. "=" ist ein Stringvergleich.

  3. $0, das normalerweise den Skriptnamen enthält, wird für den Parameter benutzt.

Das wäre dann eine modifizierte Version:

find ~/Musik -type d -exec bash -c 'shopt -s nullglob; for d; do f=("$d"/*.sfv); test ${#f[@]} -eq 0 && echo "$d"; done' -- {} +

Ciao

robert

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

rklm schrieb:

  1. $0, das normalerweise den Skriptnamen enthält, wird für den Parameter benutzt.

Das ist die berühmte Ausnahme von der Regel, bei bash -c gilt ausdrücklich:

-c string

Read and execute commands from string after processing the options, then exit. Any remaining arguments are assigned to the positional parameters, starting with $0.

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

track schrieb:

rklm schrieb:

  1. $0, das normalerweise den Skriptnamen enthält, wird für den Parameter benutzt.

Das ist die berühmte Ausnahme von der Regel, bei bash -c gilt ausdrücklich:

-c string

Read and execute commands from string after processing the options, then exit. Any remaining arguments are assigned to the positional parameters, starting with $0.

Das ist mir klar, aber das ist eine blöde Ausnahme, da for nur über die Parameter ab $1 iteriert.

1
2
3
$ bash -c 'for x; do echo $x; done' a b c
b
c

Wenn man mehrere Argumente verarbeiten will, ist die Variante besser, die erst ab $1 zuweist, weil man dann leichter alle Werte uniform verarbeiten kann.

Ciao

robert

synapsen.stau

(Themenstarter)
Avatar von synapsen.stau

Anmeldungsdatum:
27. Mai 2007

Beiträge: 266

rklm schrieb:

Das wäre dann eine modifizierte Version:

find ~/Musik -type d -exec bash -c 'shopt -s nullglob; for d; do f=("$d"/*.sfv); test ${#f[@]} -eq 0 && echo "$d"; done' -- {} +

Diese Version funktioniert bei mir auch wunderbar Ich danke euch beiden für die hilfe.... ☺

Antworten |