Eu tenho muitos arquivos e pastas em uma pasta específica e quero excluir todos eles; no entanto, eu queria manter os arquivos X, Y e Z.
Existe uma maneira de fazer algo como: rm * | but NOT grep | X or Y or Z
Eu tenho muitos arquivos e pastas em uma pasta específica e quero excluir todos eles; no entanto, eu queria manter os arquivos X, Y e Z.
Existe uma maneira de fazer algo como: rm * | but NOT grep | X or Y or Z
Respostas:
Em vez de usar rm, pode ser mais fácil usar o find . Um comando como esse excluiria tudo, exceto um arquivo chamado exatamente 'arquivo'
find . \! -name 'file' -delete
Muitas versões do devem poder suportar globbing e correspondência de expressão regular.
Você também pode canalizar a saída de find para rm também
find . \! -name '*pattern*' -print0 | xargs --null rm
-delete
arquivos e quais serão salvos removendo -delete
e \!
.
find
é recursivo! para que todos os subdiretórios de arquivos que não correspondam ao ' padrão ' sejam excluídos também
Usando zsh, with setopt EXTENDED_GLOB
, usando o ~
operador ( exceto )
rm -- *~(x|y|z)
ou ^
operador (negação):
rm -- ^(x|y|z)
Mas você provavelmente deve mover os arquivos para outro lugar e excluir tudo. É muito mais seguro em termos de deslizamentos de dedos, como pressionar Enter muito cedo.
Versões posteriores do bash têm a extglob
opção de shell que fornece uma sintaxe para fazer o que você deseja (verifique sua página de manual em "Expansão do nome do caminho" para ver se a versão instalada possui):
$ shopt -s extglob # turn on extended globbing
$ rm !(X|Y|Z)
Para testar, sugiro que você primeiro substitua rm
por echo
para ver se a lista de arquivos a serem excluídos é o que você espera.
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r
Atenção: Execute o comando e, se os arquivos a serem excluídos forem os corretos, execute-o novamente e exclua o caractere de hash "#".
Se os nomes dos arquivos forem mais complicados, faça isso.
ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r
Novamente, primeiro observe os resultados e remova o sinal de hash.
Esta versão - como sugerido nos comentários - salva alguns caracteres e parece um pouco mais clara.
ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r
a
, b
e a b
o primeiro programa for excluído - se você colocar ab na parte grep: "^[ab]$"
a
e, b
mas não a b
, oponha-se apenas às suas intenções. O segundo comando fará o mesmo. E o terceiro também. Você não deve usar 'ls' em scripts, com exceções muito, muito raras. Apenas não faça isso.
Mova os arquivos que você deseja manter longe. Suba um nível, exclua a pasta. Recrie a pasta e mova esses arquivos de volta.
/
, hein? Não é muito prático. c) Tentar remover todos os arquivos do seu $HOME
computador também não é prático.
Isto é o que eu configurei como um script .sh para um gancho de logout do OSX / MacOS, funciona bem o suficiente.
#! /bin/bash
for dir in /PathToFolder/*
do
if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then
echo ${dir}
sudo rm -R $dir user
dscl . -delete $dir
fi
done
exit 0
Com o GNU-find, você pode usar a opção -delete, que remove os diretórios, se vazios também:
find tmp -not -name X -not -name Y -not -name Z -delete
find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -delete
é uma maneira de contornar isso.
tmp
se não houver arquivos X
/ Y
/ Z
. Nota !
como o equivalente padrão de GNU do -not
( -delete
também é uma extensão GNU)