staging.inyokaproject.org

alle Ordner löschen, die *nur* jpg's und system files enthalten

Status: Ungelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

McT1357

Anmeldungsdatum:
20. Januar 2019

Beiträge: 1

Hallo,

ich bin auf der Suche nach einem Befehl, der in einem Verzeichnisbaum alle Ordner löscht, in denen nur *.jpg, *.db und *.ini Dateien enthalten sind.

Hintergrund: mir ist meine Musikdatenbank abgeraucht und jetzt habe ich auf meiner NAS jede Menge Ordner, in denen keine mp3s, m4as, m4vs etc. mehr drin sind. Stattdessen nur noch die Album Covers und von windows damals generierte Systemfiles (thumbs.db's und desktop.ini's).

Nun möchte ich das Verzeichnis aufräumen und über eine Shell alle Ordner löschen, die keine Musik mehr enthalten.

Da gibt es doch bestimmt eine nette Kombination aus find und exec rm... ist mir nur zu heikel es einfach mal auf gut Glück auszuprobieren, da ich Linux-Neuling bin.

Danke vorab!

Grüße, McT

Chemnitzsurfer

Anmeldungsdatum:
26. April 2011

Beiträge: 882

evtl. könnte das mit

1
find /ORDNERPFAD -type d -size -1024KB -delete

gehen. Damit sollten alle Ordner kleiner 1Mb gelöscht werden. Die Coverbilder sind selten über 500KB groß und die Systemdatein 1-10 KB?

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7795

Vorsicht... das -size bezieht sich nicht auf die Größe der enthaltenen Dateien. Also das ist schon noch etwas komplizierter.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Vielleicht etwas in der Art:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash
shopt -s nullglob
for i
do
    while read -r -d $'\0' directory ; do
        pushd "$directory" >/dev/null
        delete=1
        got_offending_file=0
        for p in *;
        do
            if [ -d "$p" ]  # don't delete a directory with subdirectories
            then
                delete=0
                break
            fi
            case "$p" in
                *.jpg|*.db|*.ini)
                    got_offending_file=1
                    continue
                    ;;

                *)
                    delete=0
                    break
                    ;;
            esac
        done
        [ $delete -eq 1 ] && [ $got_offending_file -eq 1 ] && echo "rm -r $directory"
        popd >/dev/null
    done < <(find "$i" -type d -print0)
done

Wenn das Ergebnis passt, kannst du den echo-Befehl in Zeile 28 rausnehmen und das erste Anführungszeichen vor $directory platzieren.

ChickenLipsRfun2eat Team-Icon

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Hallo!

Du kannst nach mehreren Dateiendungen suchen, wenn du das in Klammern setzt. Für dein Beispiel:

1
find /my/music/ -type f \( -iname \*.jpg -o -iname \*.db -o -iname \*.ini \) -ls

Dieser Befehl listet lediglich die Dateien auf, kann also gefahrlos ausprobiert werden. find kann aber auch rm.

Im Anschluss könntest du alle leeren Ordner entfernen lassen.

1
find /my/music/ -type d -depth -exec rmdir {} \;

Das ist zwar die "Holzhammermethode", weil einfach jedes Verzeichnis entfernt werden soll, aber wenn noch Dateien drin sind, scheitert rmdir. -depth bewirkt, dass er rekursiv abarbeitet, bzw. präziser von der tiefsten Ebene aus anfängt.

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7795

In manchen Dateisystemen findest du Verzeichnisse ohne Unterverzeichnisse so:

find /home/music -type d -links 2

Wenn das klappt, dann eine Liste von Verzeichnissen die NICHT gelöscht werden sollen so:

find /home/music -type d -links 2 -exec find {} -type f '!' '(' -iname '*.jpg' -o -iname '*.db' -o -iname '*.ini' ')' -printf '%h\n' ';' | uniq

Die Umkehrung davon (zu löschende Verzeichnisse)

(
    find /home/music -type d -links 2
    find /home/music -type d -links 2 -exec find {} -type f '!' '(' -iname '*.jpg' -o -iname '*.db' -o -iname '*.ini' ')' -printf '%h\n' ';' | uniq
) | sort | uniq -u

Das funktioniert indem erst alle Verzeichnisse aufgelistet werden, dann alle Verzeichnisse die NICHT gelöscht werden sollen, und dann nur die Verzeichnisse die in der Liste nicht doppelt vorkamen. (also alle Verzeichnisse minus die NICHT zu löschenden, bleiben die löschbaren übrig).

Wie du das dann löschst lasse ich hier mal aus, das darfst du dann auf eigene Verantwortung tun. 😛

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9837

McT1357 schrieb:

[…] Musikdatenbank abgeraucht […] Nun möchte ich das Verzeichnis aufräumen und über eine Shell alle Ordner löschen, die keine Musik mehr enthalten.

Ich würde nach den Musikdateien suchen und diese samt Ordner-Hierarchie kopieren. Danach das alte Verzeichnis löschen.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

In Ruby könntest Du die entsprechenden Verzeichnisse so erkennen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
require 'pathname'

dirs = Hash.new {|h, k| h[k] = false}

Pathname(ARGV.shift).find do |f|
  d = f.dirname
  dirs[d] ||= (f.file? && /\.(?:jpg|ini|db)\z/ !~ f.basename.to_s)
end

#require 'pp'
#pp dirs

dirs.each do |d, flag|
  puts d unless flag
end
Antworten |