Excluindo arquivos com espaços em seus nomes

10

Estou tentando excluir todos os arquivos com um espaço em seus nomes. Eu estou usando o seguinte comando. Mas está me dando um erro

Comando: ls | egrep '. ' | xargs rm

Aqui, se eu estiver usando apenas o ls | egrep '. 'comando, ele estará me dando todo o nome do arquivo com espaços nos nomes dos arquivos. Mas quando estou tentando passar a saída para rm, todos os espaços (à esquerda ou à direita) são excluídos. Portanto, meu comando não está sendo executado corretamente.

Alguma dica sobre como excluir o arquivo com pelo menos um espaço em seu nome?

Anuj
fonte

Respostas:

29

Você pode usar globbing padrão no rmcomando:

rm -- *\ *

Isso excluirá qualquer arquivo cujo nome contenha um espaço; o espaço é escapado para que o shell não o interprete como um separador. A adição --evitará problemas com nomes de arquivos iniciados por traços (eles não serão interpretados como argumentos por rm).

Se você deseja confirmar cada arquivo antes de ser excluído, adicione a -iopção:

rm -i -- *\ *
Stephen Kitt
fonte
4
Definitivamente, você deseja executar isso echoprimeiro, para evitar erros de digitação. Adicione echona frente e ele imprimirá todos os arquivos que serão removidos.
Riking
1
Anuj, a razão pela qual isso tem mais votos positivos é que, embora findseja poderoso, às vezes você não precisa matar o frango com uma metralhadora. Os administradores do UNIX geralmente não recorrem a find(por exemplo) "remover todos os arquivos que começam com a letra A" ... um simplesmente rm A*. Da mesma forma, para remover arquivos que contêm espaços, a rm pode fazer o trabalho. Em outras palavras, não se deixe enganar, porque o espaço é invisível e é tratado especialmente pela concha. Simplesmente escape, como Stephen Kitt fez, e você pode pensar nisso como qualquer outro personagem.
Mike S
14

Eu evitaria analisar a lssaída

Por que não :

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

Nenhum problema com rm:-).

Embora isso seja recursivo e exclua todos os arquivos com espaço no diretório atual e nos diretórios aninhados, conforme mencionado nos comentários.

solstício
fonte
4
(1) você pode usar em -name '* *'vez do regex; e (2) você pode usar -print0 | xargs -0 rm -ipara resolver a preocupação de @ StephenKitt.
Kevin
1
Não há necessidade xargs. Basta usar-exec rm -i '{}' +
R .. GitHub PARE DE AJUDAR ICE
1
@Mhmd Tem mais armadilhas do que um console de jogos de 8 bits. mywiki.wooledge.org/ParsingLs
Daenyth
1
Se você deseja evitar subdiretórios, use find . -maxdepth 1 -name '* *' -delete.
Mikkel
1
@BenjaminW. fixo?
SolsTiCe 13/1118
6

Veja este nome suponha "arquivo estranho"

Solução um

rm strange\ file

solução dois

rm "strange file"

solução três

ls -i "strange file"

você vê o inode então

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

No caso de nomes de arquivos muito estranhos, como

!-filename or --filename

usar

rm ./'!-filename'
elbarna
fonte
4

De man xargs

O xargs lê itens da entrada padrão, delimitados por espaços em branco (que podem ser protegidos com aspas duplas ou simples ou uma barra invertida) ou novas linhas e executa o comando (o padrão é / bin / echo) uma ou mais vezes com os argumentos iniciais seguidos por itens lidos na entrada padrão. Linhas em branco na entrada padrão são ignoradas.

Podemos (principalmente) corrigir seu comando inicial alterando o delimitador xargs para uma nova linha:

ls | egrep '. ' | xargs -d '\n' rm (não faça isso ... continue lendo)

Mas e se o nome do arquivo contiver uma nova linha?

touch "filename with blanks and newline"

Como os nomes de arquivos do Unix podem conter espaços em branco e novas linhas , esse comportamento padrão geralmente é problemático; nomes de arquivos contendo espaços em branco e / ou novas linhas são processados ​​incorretamente pelo xargs. Nessas situações, é melhor usar a opção -0 , que evita esses problemas.

ls é realmente uma ferramenta para consumo direto de um ser humano ; em vez disso, precisamos usar o findcomando que pode separar os nomes de arquivos com um caractere nulo ( -print0). Também precisamos dizer ao grep para usar caracteres nulos para separar a entrada ( -z) e a saída ( -Z). Finalmente, dizemos ao xargs que também use caracteres nulos ( -0)

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

anjsimmo
fonte
1

Você pode usar:

find . -name '* *' -delete
Max ZHUANG
fonte
rm - * \ * parece melhor
Max ZHUANG
Além disso, isso foi abordado pelo comentário de Kevin sobre a resposta do solsTiCe.
G-Man diz 'Reinstate Monica'
-1

Para fazer dessa maneira, você precisará da -Zopção grep e da -0opção xargs. Mas eu não faria dessa maneira ( lsnão é a ferramenta certa para o trabalho, há muitos problemas em fazer o computador ler sua saída).

Veja outras respostas para uma maneira melhor.


Além disso

ls | …é equivalente a ls -d *eecho * | …

Todos com problemas. Portanto, não use lsassim, use uma solução de outra resposta.

ctrl-alt-delor
fonte
Além disso, ls *quando os pipes emitem os nomes dos arquivos delimitados por nova linha. echo(pelo menos algumas echoimplementações) expande seqüências de barra invertida. grep -Zé para escrever nomes de arquivo delimitados por NUL ao usar -l, não ajudará aqui. Se você quis dizer -z, isso também não ajudará, pois a maioria das lsimplementações não possui uma opção para gerar nomes de arquivos delimitados por NUL. Alguém poderia fazer algo como isso printf '%s\0' * | grep -z ' ' | xargs -r0 rm -f.
Stéphane Chazelas
1
@Kusalananda Acho que consertei.
Ctrl-alt-delor 13/11/19