Wie lösche ich Ordner mit n oder weniger Dateien?

7

Ich muss einige Ordner bereinigen und möchte Verzeichnisse entfernen, die 10 oder weniger Dateien enthalten. Ich habe versucht, mir GNUs anzusehen find, aber es gab nichts, was mit der Anzahl der Dateien in einem Verzeichnis zu tun hatte. Mit welchen Befehlen soll ich das erreichen?


quelle
Sie müssen angeben, ob es sich um ein rekursives oder ein flaches Verzeichnis handelt. Das macht einen großen Unterschied. Auch wenn Sie Elemente (auch Unterverzeichnisse) oder ausschließlich Dateien meinen.
Jacob Vlijm
Könnten Sie bitte ein Beispiel in Ihre Frage aufnehmen, um das Problem zu veranschaulichen? Ich bin mir nicht sicher, ob ich alle Details verstehe.
David Foerster
CLOSE_VOTERS Was haben Sie aus dieser klaren Frage nicht verstanden?
Anwar

Antworten:

3

Eine Möglichkeit wäre, mit findder -execAktion 's einen benutzerdefinierten Test der Anzahl der Dateien auszuführen.

Man könnte einen zweiten findBefehl zusammen mit verwenden wc, um Dateien in jedem Verzeichnis zu finden und zu zählen, aber wahrscheinlich wäre eine bessere Option, das Globbing zu schälen, um die Dateinamen in ein Array zu schlürfen, und dann einen logischen Wert zurückzugeben, der angibt, ob die Größe des Arrays kleiner ist als die Schwelle dh

files=( dir/* ); ((${#files[@]} < 10))

Dass sie alle zusammen sollten wir in der Lage sein listen alle Unterverzeichnisse mit weniger als 10 Dateien (einschließlich der Unterverzeichnisse) mit

find . -depth -type d ! -name '.' -exec bash -c '
  shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < ${2:-10}))
  ' bash {} 10 \; -print0 | xargs -0

(Sie können die Zahl 10nach dem bash {}für verschiedene Schwellenwerte anpassen. Bei der ${2:-10}Parametererweiterung werden standardmäßig 10 Dateien verwendet, wenn kein zweites Argument angegeben wird.) Zum Beispiel gegeben

$ tree .
.
├── bar
│   ├── file1
│   ├── file2
│   ├── file3
│   ├── file4
│   ├── file5
│   ├── file6
│   ├── file7
│   ├── file8
│   ├── file9
│   └── other file
├── baz
│   ├── other file
│   └── subdir
└── foo
    └── somefile

4 directories, 12 files

dann

find . -depth -type d ! -name '.' -exec bash -c '
  shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < "${2:-10}"))
  ' bash {} 10 \; -print0 | xargs -0
./foo ./baz/subdir ./baz

Wenn dies das Richtige zu sein scheint, können Sie sie tatsächlich durch Hinzufügen entfernen, rm -rf aber seien Sie bitte sehr vorsichtig - denken Sie daran, dass es kein "Rückgängigmachen" gibt.

find . -depth -type d ! -name '.' -exec bash -c '
  shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < ${2:-10}))
' bash {} 10 \; -print0 | xargs -0 rm -rf

(Das xargskönnte beseitigt werden, indem eine andere -execAktion verwendet wird, um rmdirekter auszuführen , aber die obige Formulierung erleichtert die Verallgemeinerung - Drucken, Statisieren, Entfernen oder was auch immer.)

Beachten Sie, dass dies rekursiv erfolgt, dh ein Verzeichnis, das anfänglich mehr als nDateien einschließlich Unterverzeichnisse enthält, kann entfernt werden, da einige dieser Unterverzeichnisse selbst entfernt werden, findum den Verzeichnisbaum zu sichern. Das aktuelle Verzeichnis ist ausdrücklich vor einem möglichen Löschen durch den ! -name '.'Test geschützt .

Wenn Sie es nicht benötigen, um rekursiv zu handeln, können Sie einfach Verzeichnisse durchlaufen und dieselbe Dateizählung und Testlogik ausführen, z. B. um alle Verzeichnisse der ersten Ebene zu entfernen, die weniger als 10 Dateien im aktuellen Verzeichnis enthalten

shopt -s nullglob
for d in */; do
  files=( "$d"/* )
  ((${#files[@]} < 10)) && echo rm -rf -- "$d"
done 
Steeldriver
quelle
0

Ich habe das nicht vollständig getestet, aber es sollte funktionieren. Sie können dies auch verwenden find, um dies zu erreichen.

# Loop over all files
for dir in * **/*; do
    # Make sure this is a directory
    if [ -d "${dir}" ]; then
        # Get the number of files (not including directories) in this directory
        FILE_COUNT=`ls $dir -1 | grep -v / | wc -l`
        # Check if it's less than 10
        if [ $FILE_COUNT -lt 10 ]; then
            # Delete the directory
            rm -rf "${dir}"
        fi
    fi
done
Rymac
quelle
Beachten Sie, dass bei Verwendung wc -ldie falsche Nummer angegeben wird, wenn in Dateinamen Zeilenumbrüche enthalten sind.
Wjandrea