Como remover todos os itens de uma pasta, exceto os itens grep

3

Eu gostaria de criar um script de limpeza para um diretório usado para backups.

Por exemplo: Eu tenho 10 arquivos em um diretório e eles incluem numeração no nome do arquivo

como:

b_100
b_101
b_102
b_103
b_104
b_105
b_106
b_107
b_108
b_109
b_110

Eu gostaria de pesquisar arquivos específicos dentro do diretório de b_105 a b_110 e remover todo o resto. Significado b_100 b_101 b_102 b_103 b_104 serão todos removidos / apagados.

Se eu quiser fazer um grep em um arquivo dentro de um diretório como b_110, remova tudo que não estiver em grep.

    
por Christopher Karsten 22.09.2016 / 12:45

5 respostas

6

com zsh :

setopt extendedglob
rm -rf -- ^b_<105-110>

Remove todos os arquivos e diretórios não ocultos, exceto aqueles cujo nome começa com b_ e termina em um número decimal cujo valor está compreendido entre 105 e 110.

Se você quiser apenas remover arquivos b_* :

rm -rf -- b_(*~<105-110>)

~ sendo o operador zsh glob para exceto .

Ou você poderia fazer:

all_b_files=(b_*)
to_exclude=(b_{105..110})
rm -rf -- ${all_b_files:|to_exclude}

Com ksh93 ou bash -O extglob (ou zsh -o kshglob ):

set -- b_{105..110} # set positional parameters to b_105 b_106...
IFS='|'             # used for joining positional parameters in "$*"
pattern="$*"        # prepare extended ksh glob
IFS=                # empty IFS to prevent splitting
rm -rf -- !($pattern)
    
por 22.09.2016 / 13:17
3

Com o bash e o extended globbing ativado, você pode fazer:

shopt -s extglob 
glob=$(echo b_{105..110} | sed 's/ /|/g')
rm -- !($glob)

Isso primeiro definirá a variável glob para a saída de:

$ echo b_{105..110} | sed 's/ /|/g'
b_105|b_106|b_107|b_108|b_109|b_110

Portanto, uma lista dos nomes de arquivos desejados separados por | . Em seguida, o comando rm -- !($glob) removerá todos os arquivos que não corresponderem a $glob .

    
por 22.09.2016 / 15:02
1

Você pode usar localizar para listar todos os arquivos correspondentes em um diretório:

find /path/to/directory -not -name "file_name_to_keep" -type f

Você pode, então, canalizar a saída do find em xargs ou apenas usar o recurso de execução ou exclusão integrado do find.

find /path/to/directory -not -name "file_name_to_keep" -type f -exec rm "{}" \;

ou usando a opção de exclusão integrada do GNU find

find /path/to/directory -not -name "file_name_to_keep" -type f -delete

Mais discussões sobre os vários métodos de exclusão baseados na saída find aqui: Como excluir diretórios com base na saída 'find'?

    
por 22.09.2016 / 13:10
1

Se você estiver procurando por uma string dentro do arquivo, você pode usar -L:

grep -L "string" ./* | xargs rm

Como alternativa - como você disse que estava usando isso para backups, você poderia usar find para encontrar todos os arquivos com uma data anterior e removê-los com -exec . Essa seria uma solução melhor do que um grep se você estiver usando data-5 dias, por exemplo.

    
por 22.09.2016 / 13:27
0

Eu não li a pergunta toda, mas quando você diz "exceto os itens grepped", isso imediatamente me faz pensar que você não sabe o parâmetro -v grep, que significa "Tudo, exceto ..." Por exemplo:

ls -ltra | grep -v .txt

Isso mostrará uma lista de todos os arquivos, exceto os arquivos de texto.

    
por 22.09.2016 / 15:35

Tags