web-dev-qa-db-de.com

Entfernen Sie alle Dateien in einem Verzeichnis (berühren Sie keine Ordner oder Objekte darin)

Ich möchte wissen, ob rm alle Dateien in einem Verzeichnis entfernen kann (nicht jedoch die Unterordner oder Dateien in den Unterordnern).

Ich weiß, dass einige Leute verwenden:

rm -f /direcname/*.*

dies setzt jedoch voraus, dass der Dateiname eine Erweiterung hat, die nicht alle machen (ich möchte, dass alle Dateien - mit oder ohne Erweiterung) entfernt werden.

17
toop

Mit find können Sie Dateien mit -exec rm {} \; löschen, die Sie verwenden können 

find /direcname -maxdepth 1 -type f -delete

und es ist schneller. Die Verwendung von -delete impliziert die Option -depth, d. H. Prozessinhalt vor dem Verzeichnis.

34
troller
find /direcname -maxdepth 1 -type f -exec rm {} \;

Erläuterung:

  • find sucht nach Dateien und Verzeichnissen in /direcname
  • -maxdepth beschränkt die Suche nach Dateien und Verzeichnissen, die direkte Kinder von /direcname sind.
  • -type f beschränkt die Suche auf Dateien
  • -exec rm {} \; führt den Befehl rm {} für jede Datei aus (nachdem der Dateipfad anstelle von {} ersetzt wurde).
7
huon

Ich möchte wissen, ob rm alle Dateien in einem Verzeichnis entfernen kann (aber nicht die Unterordner oder Dateien in den Unterordnern)?

Das ist einfach:

$ rm folder/*

Ohne -r berührt der Befehl rm keine Unterverzeichnisse oder die darin enthaltenen Dateien. Dadurch werden nur die Dateien in folder und nicht die Unterverzeichnisse oder deren Dateien entfernt.

Sie werden sehen, dass errors Ihnen mitteilt, dass Ordner/foo ein Verzeichnis ist, das nicht entfernt werden kann, aber das ist in Ordnung für Sie. Wenn Sie diese Meldungen löschen möchten, leiten Sie einfach STDERR um:

$ rm folder/* 2> /dev/null

Der Exit-Status des rm-Befehls ist möglicherweise nicht Null, daher können Sie rm nicht auf Fehler prüfen. Wenn das wichtig ist, musst du folgende Schleife machen:

$ for file in *
> do
> [[ -f $file ]] && rm $file
> [[ $? -ne 0 ]] && echo "Error in removing file '$file'"
> done

Dies sollte in BASH funktionieren, auch wenn die Dateinamen Leerzeichen enthalten.

3
David W.

Sie können verwenden

find /direcname -maxdepth 1 -type f -exec rm -f {} \;
2
tonio

Eine Shell-Lösung (ohne die nicht standardmäßige find -maxdepth) wäre

for file in .* *; do
   test -f "$file" && rm "$file"
done
2
Jens

Unix ist nicht DOS. Es gibt kein spezielles "Erweiterungsfeld" in einem Dateinamen. Alle Zeichen nach einem Punkt sind nur ein Teil des Namens und werden als Suffix bezeichnet. Es kann mehr als ein Suffix geben, zum Beispiel .tar.gz. Das Shell-Glob-Zeichen * stimmt mit dem .-Zeichen überein. Suffixe werden dabei nicht beachtet. Der MS-DOS *.* ist also nur * In Unix.

Fast. * stimmt nicht mit Dateien überein, die mit einem . beginnen. Objekte, die mit einem führenden Punkt benannt werden, sind nach der Konvention "versteckt". Sie werden auch nicht in ls angezeigt, es sei denn, Sie geben -a an.

(Dies bedeutet, dass die Verzeichniseinträge . und .. für "self" und "parent" als ausgeblendet betrachtet werden.)

Um auch ausgeblendete Einträge zu finden, verwenden Sie .*

Der Befehl rm entfernt keine Verzeichnisse (wenn er nicht rekursiv mit -r bearbeitet wird). Versuchen Sie rm <directory> und sehen Sie. Selbst wenn das Verzeichnis leer ist, wird es abgelehnt.

So entfernen Sie alle (nicht verborgenen) Dateien, Pipes, Geräte, Sockets und symbolischen Links aus einem Verzeichnis (wobei Sie die Unterverzeichnisse jedoch allein lassen):

rm /path/to/directory/*

um auch die versteckten zu entfernen, die mit . beginnen:

rm /path/to/directory/{*,.*}

Diese Syntax ist eine Klammererweiterung. Klammererweiterung ist kein Mustervergleich; es ist nur eine Abkürzung für das Generieren mehrerer Argumente, in diesem Fall:

rm /path/to/directory/* /path/to/directory/.*

diese Erweiterung erfolgt zuerst und dann das Globbing, um die zu löschenden Namen zu generieren.

Beachten Sie, dass verschiedene hier veröffentlichte Lösungen verschiedene Probleme haben:

find /path/to/directory -type f -delete

# -delete is not Unix standard; GNU find extension
# without -maxdepth 1 this will recurse over all files
# -maxdepth is also a GNU extension
# -type f finds only files; so this neglects to delete symlinks, fifos, etc.

Die GNU find-Lösungen haben den Vorteil, dass sie funktionieren, auch wenn die Anzahl der zu löschenden Verzeichniseinträge sehr groß ist: zu groß, um sie mit einem einzigen Aufruf an rm zu übergeben. Ein weiterer Vorteil besteht darin, dass der integrierte Code -delete keine Probleme mit der Übergabe lustiger Pfadnamen an einen externen Befehl hat.

Die tragbare Lösung für das Problem zu vieler Verzeichniseinträge besteht darin, die Einträge mit ls aufzulisten und an xargs weiterzuleiten:

( cd /path/to/directory ; ls -a | xargs rm -- )

Die Klammern bedeuten "diese Befehle in einem Unterprozess ausführen"; Auf diese Weise wird die Wirkung von cd vergessen, was beim Scripting hilfreich ist. ls -a enthält die versteckten Dateien.

Wir fügen jetzt einen -- hinter rm ein, was bedeutet "dies ist die letzte Option; alles andere ist ein Nichtoptionsargument". Dies schützt uns vor Verzeichniseinträgen, deren Namen von Optionen nicht unterschieden werden können. Was passiert, wenn eine Datei -rf heißt und das erste Argument endet? Dann haben Sie rm -rf ..., der Unterverzeichnisse abblasen wird.

1
Kaz

Einige Shells, insbesondere zsh und vielleicht bash Version 4 (aber nicht Version 3), haben eine Syntax, um dies zu tun.

Mit zsh tippen Sie vielleicht einfach

rm /dir/path/*(.)

und wenn Sie eine Datei entfernen möchten, deren Name mit foo beginnt, rekursiv in Unterverzeichnissen, können Sie dies tun

rm /dir/path/**/foo*(.)

die Doppelsternfunktion ist (mit IMHO besser interaktiver Abschluss) meiner Meinung nach ausreichend, um für interaktive Shells auf zsh zu wechseln. YMMV

Der Punkt in Klammern heißt, dass nur Dateien (keine Symlinks oder Verzeichnisse) von der zsh-Shell erweitert werden sollen.

Am einfachsten geht das:

rm *

Um Verzeichnisse zu entfernen, müssen Sie die Option -r angeben

rm -r

ihre Verzeichnisse und alles, was darin enthalten ist, werden also nicht mit entfernt

rm *

in der Manpage für rm sollen Dateien entfernt werden, weshalb dies funktioniert

0
Musher

Simple Shell Globbing erledigt:

% tree
.
├── 1
├── 2
├── 3
├── 4
├── 5
└── bar
    ├── a
    ├── b
    ├── c
    ├── d
    └── e

1 directory, 10 files

% rm -f *
rm: cannot remove ‘./bar’: Is a directory

% tree .
.
└── bar
    ├── a
    ├── b
    ├── c
    ├── d
    └── e

1 directory, 5 files

wie in Jens 'Antwort müssen Sie möglicherweise einen zweiten rm -f .* hinzufügen. Dies ist jedoch nur der Fall, wenn Sie versteckte Dateien in Ihrem Hauptverzeichnis erwarten. Es ist nicht erforderlich, nach Typ (test -f) zu suchen, da die rm -f-Option keine Verzeichnisse entfernt. Dadurch werden jedoch auch "spezielle" Dateien wie symbolische Links und Blockgeräte gelöscht.

0
sleblanc