web-dev-qa-db-fra.com

Supprimer tous les fichiers / répertoires sauf un fichier

J'ai un répertoire contenant un grand nombre de fichiers. Je souhaite supprimer tous les fichiers à l'exception de file.txt. Comment puis-je faire cela?

Il y a trop de fichiers pour supprimer individuellement les fichiers indésirables et leurs noms sont trop divers pour être utilisés * pour les supprimer tous sauf ce fichier.

Quelqu'un a suggéré d'utiliser

rm !(file.txt)

Mais ça ne marche pas. Il renvoie:

Badly placed ()'s 

Mon système d'exploitation est Scientific Linux 6.

Des idées?

275
Kantura

POSIX:

find . ! -name 'file.txt' -type f -exec rm -f {} +

supprimera tous les fichiers normaux (récursivement, y compris ceux cachés) sauf file.txt. Pour supprimer des répertoires, remplacez -type f Par -type d Et ajoutez l'option -r À rm.

Dans bash, pour utiliser rm -- !(file.txt), vous devez activer extglob :

$ shopt -s extglob 
$ rm -- !(file.txt)

(ou en appelant bash -O extglob)

Notez que extglob ne fonctionne que dans bash et la famille Korn Shell. Et l'utilisation de rm -- !(file.txt) peut provoquer une erreur Argument list too long.

Dans zsh, vous pouvez utiliser ^ Pour annuler le modèle avec extendedglob activé:

$ setopt extendedglob
$ rm -- ^file.txt

ou en utilisant la même syntaxe avec ksh et bash avec les options ksh_glob et no_bare_glob_qual activées.

323
cuonglm

Une autre prise dans une direction différente (s'il n'y a pas d'espace dans les noms de fichiers)

ls | grep -v file.txt | xargs rm

ou (fonctionne même s'il y a des espaces dans les noms de fichiers)

ls | grep -v file.txt | parallel rm

de man grep:

 -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v is specified by POSIX)
124
Sebastian

Conserver une copie, supprimer tout, restaurer la copie:

{   rm -rf *
    tar -x
} <<TAR
$(tar -c $one_file)
TAR

En une seule ligne:

{ rm -rf *; tar -x; } <<< $(tar -c $one_file)

Mais cela nécessite un Shell qui prend en charge les chaînes ici.

35
mikeserv

vous y pensez tous trop.

cd ..
mv fulldir/file.txt /tmp/
rm -rf fulldir
mkdir fulldir
mv /tmp/file.txt fulldir/

Terminé.

MODIFIER En fait, plus simple:

cd ..
ln fulldir/file.txt ./
rm -rf fulldir
mkdir -p fulldir
mv file.txt fulldir/
26
Shadur

Sur mon système d'exploitation Scientific Linux 6, cela fonctionne:

shopt -s extglob
rm !(file.txt)

J'ai également Debian 32 bits installé sur une machine virtuelle. Ce qui précède ne fonctionne pas, mais ce qui suit:

find . -type f ! -name 'file.txt' -delete
19
Kantura

Utilisez rm !("file.txt") au lieu de rm !(file.txt)

12
www.wishinfo.net

Juste pour donner une réponse différente, vous pouvez utiliser le comportement par défaut de rm pour ne pas supprimer les dossiers:

mkdir tmp && mv file.txt tmp  # create tmp dir and move files there
rm                            # delete all other files
mv tmp/* . && rm -rf tmp      # move all files back and delete tmp dir
8
Nithin

Je trouve que cette approche est très simple, fonctionne et ne nécessite aucune extension spéciale (que je sache!)

ls --hide=file.txt | xargs rm
4
2-bits