Suppression de fichiers avec des espaces dans leurs noms

10

J'essaie de supprimer tous les fichiers avec un espace dans leurs noms. J'utilise la commande suivante. Mais ça me donne une erreur

Commande: ls | egrep '. ' | xargs rm

Ici, si j'utilise uniquement la ls | egrep '. 'commande, cela me donne tout le nom de fichier avec des espaces dans les noms de fichiers. Mais lorsque j'essaie de passer la sortie à rm, tous les espaces (en tête ou en fin) sont supprimés. Donc ma commande ne s'exécute pas correctement.

Des conseils sur la façon de supprimer le fichier ayant au moins un espace dans leur nom?

Anuj
la source

Réponses:

29

Vous pouvez utiliser le globbing standard sur la rmcommande:

rm -- *\ *

Cela supprimera tout fichier dont le nom contient un espace; l'espace est échappé afin que le shell ne l'interprète pas comme un séparateur. L'ajout --évitera les problèmes avec les noms de fichiers commençant par des tirets (ils ne seront pas interprétés comme des arguments par rm).

Si vous souhaitez confirmer chaque fichier avant sa suppression, ajoutez l' -ioption:

rm -i -- *\ *
Stephen Kitt
la source
4
Vous voudrez certainement exécuter cela par le biais d'une echopremière, pour vous protéger des fautes de frappe. Ajoutez echoà l'avant et il imprimera tous les fichiers qu'il va supprimer.
Riking
1
Anuj, la raison pour laquelle cela a le plus de votes positifs est que, bien que findpuissant, il n'est parfois pas nécessaire de tuer le poulet avec une mitrailleuse. Les administrateurs UNIX ne recourraient généralement pas find(par exemple) à "supprimer tous les fichiers commençant par la lettre A" ... un serait tout simplement rm A*. De même, pour supprimer les fichiers contenant des espaces, rm peut faire le travail. En d'autres termes, ne vous laissez pas berner car l'espace est invisible et est traité spécialement par la coque. Échappez-vous simplement à lui, comme l'a fait Stephen Kitt, et vous pouvez y penser comme n'importe quel autre personnage.
Mike S
14

J'éviterais d'analyser la lssortie

Pourquoi pas :

find . -type f -name '* *' -delete

Pas de problème avec rm:-).

Bien que cela soit récursif et supprimera tous les fichiers avec de l'espace dans le répertoire actuel et les répertoires imbriqués, comme mentionné dans les commentaires.

solstice
la source
4
(1) vous pouvez utiliser à la -name '* *'place de l'expression régulière; et (2) vous pouvez utiliser -print0 | xargs -0 rm -ipour répondre aux préoccupations de @ StephenKitt.
Kevin
1
Pas besoin de xargs. Il suffit d'utiliser-exec rm -i '{}' +
R .. GitHub STOP HELPING ICE
1
@Mhmd Elle a plus d'embûches qu'une console de jeu 8 bits. mywiki.wooledge.org/ParsingLs
Daenyth
1
Si vous souhaitez éviter les sous-répertoires, utilisez find . -maxdepth 1 -name '* *' -delete.
Mikkel
1
@BenjaminW. fixe?
solsTiCe
6

Regardez ce nom supposé "fichier étrange"

Solution un

rm strange\ file

solution deux

rm "strange file"

solution trois

ls -i "strange file"

vous voyez alors l'inode

find . -inum "numberoofinode" -exec rm {} \;

En cas de noms de fichiers très étranges comme

!-filename or --filename

utilisation

rm ./'!-filename'
elbarna
la source
4

De man xargs

xargs lit les éléments de l'entrée standard, délimités par des espaces (qui peuvent être protégés par des guillemets doubles ou simples ou une barre oblique inverse) ou des sauts de ligne, et exécute la commande (par défaut est / bin / echo) une ou plusieurs fois avec tous les arguments initiaux suivis par les éléments lus à partir de l'entrée standard. Les lignes vides sur l'entrée standard sont ignorées.

Nous pouvons (principalement) corriger votre commande initiale en changeant le délimiteur xargs en une nouvelle ligne:

ls | egrep '. ' | xargs -d '\n' rm (ne faites pas ça ... lisez la suite)

Mais que faire si le nom de fichier contient une nouvelle ligne?

touch "filename with blanks and newline"

Étant donné que les noms de fichiers Unix peuvent contenir des espaces et des sauts de ligne , ce comportement par défaut est souvent problématique; les noms de fichiers contenant des espaces et / ou des retours à la ligne sont mal traités par xargs. Dans ces situations, il est préférable d' utiliser l'option -0 , ce qui évite de tels problèmes.

ls est vraiment un outil de consommation directe par un humain , nous devons plutôt utiliser la findcommande qui peut séparer les noms de fichiers avec un caractère nul ( -print0). Nous devons également dire à grep d'utiliser des caractères nuls pour séparer l'entrée ( -z) et la sortie ( -Z). Enfin, nous demandons à xargs d'utiliser également des caractères nuls ( -0)

find . -type f -print0 | egrep '. ' -z -Z | xargs -0 rm

anjsimmo
la source
1

Vous pouvez utiliser:

find . -name '* *' -delete
Max ZHUANG
la source
rm - * \ * semble mieux
Max ZHUANG
En outre, cela a été couvert par le commentaire de Kevin sur la réponse de solsTiCe.
G-Man dit `` Réintègre Monica '' le
-1

Pour ce faire, vous aurez besoin de l' -Zoption grep et de l' -0option xargs. Mais je ne le ferais pas de cette façon (ce lsn'est pas le bon outil pour le travail, il y a beaucoup de problèmes pour que l'ordinateur lise sa sortie).

Voir d'autres réponses pour une meilleure façon.


Également

ls | …est équivalent à ls -d *etecho * | …

Qui ont tous des problèmes. Par conséquent, n'utilisez pas lscomme ça, utilisez une solution d'une autre réponse.

ctrl-alt-delor
la source
De plus, ls *lorsque les canaux sortent les noms de fichiers délimités par des sauts de ligne. echo(au moins certaines echoimplémentations) étend les séquences de barre oblique inverse. grep -Zsert à écrire des noms de fichiers délimités NUL lors de l'utilisation -l, cela n'aidera pas ici. Si vous vouliez dire -z, cela n'aidera pas non plus car la plupart des lsimplémentations n'ont pas d'option pour sortir les noms de fichiers délimités NUL. On pourrait faire quelque chose comme ça printf '%s\0' * | grep -z ' ' | xargs -r0 rm -fcependant.
Stéphane Chazelas
1
@Kusalananda Je pense que je l'ai corrigé.
ctrl-alt-delor