Remover arquivos sem string no nome

9

Quero remover arquivos que não tenham a sequência '999' (sem a '') em seu nome.

Eu tentei:

grep -vlr 999 . | xargs -0 rm -f --
find . -print0 | grep --null-data -v 999 | xargs -0 rm --

Mas nenhum deles funciona. Estou usando o macOS Sierra, com o bash: 3.2.57.

plr
fonte
2
grep -lfaz com que ele liste os arquivos nos quais uma correspondência foi encontrada (ou não encontrada -v) no conteúdo , não no nome do arquivo. grepsempre corresponde ao conteúdo dos arquivos que você especificar, nunca aos nomes.
JoL

Respostas:

18

Usando um padrão de globbing estendido em bash:

rm ./!(*999*)

Isso precisa shopt -s extglobestar ativado (e também por segurança, shopt -s failglobpara que nenhum arquivo com o nome incomum !(*999*)seja removido por engano se todos os nomes de arquivos contiverem 999). O padrão !(*999*)corresponderá a qualquer nome no diretório atual, exceto os nomes correspondentes *999*. Para também remover arquivos ocultos (arquivos cujo nome começa com um ponto ), ative também a dotglobopção

Para se importar apenas com arquivos regulares ou links simbólicos para arquivos regulares (não diretórios etc.):

for name in ./!(*999*); do [ -f "$name" ] && rm "$name"; done

O zshshell equivalente ao loop acima seria

rm ./(^(*999*))(.)

Seu primeiro comando não funcionará, pois grepprocurará nos arquivos. Ele removeria todos os arquivos que possuem linhas sem 999eles (se você tivesse adicionado a --nullopção para que ela funcione xargs -0).

Seu segundo comando não funcionará, pois o grepmacOS não suporta --null-data(no entanto, ele tem uma --nullopção, mas apenas para gerar a saída do nome do arquivo). Observe também que ele procuraria 999qualquer lugar no caminho do arquivo (incluindo componentes de diretório), não apenas o nome do arquivo.

Kusalananda
fonte
1
Você também deseja ativar a failglobopção ou ela pode remover o arquivo chamado !(*999*)se não houver outro arquivo cujo nome não contenha 999.
Stéphane Chazelas
16

Basta inverter a condição de nome em find:

find . -type f \! -name "*999*" 

Adicione -deleteou -exec rm {} +realmente remova os arquivos correspondentes.

ilkkachu
fonte
2
!está seguro bash.
Kusalananda