Como excluir alguns arquivos do mecanismo de expansão de nome de arquivo no bash?

13

Eu tenho diretórios do sistema de arquivos ubuntu no diretório raiz e copiei acidentalmente centenas de arquivos para o diretório raiz.

Eu intuitivamente tentei remover arquivos copiados, excluindo o sistema de arquivos como

rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.

bu não funciona. Qual é a maneira correta de excluir alguns diretórios ao excluir o todo?

EDIT: Nunca tente nenhum dos comandos aqui sem saber o que fazer!

    
por kenn 06.01.2017 / 21:58

3 respostas

17

Como você está usando bash :

shopt -s extglob
echo rm -rf ./!(bin|sbin|usr|...)

Eu recomendo adicionar echo no início da linha de comando quando você estiver executando algo que potencialmente pode explodir todo o sistema. Remova-a se estiver satisfeito com o resultado.

Nota: O comando acima não irá remover arquivos ocultos (aqueles cujo nome começa por um ponto). Se você quiser removê-los também, ative também a opção dotglob :

shopt -s dotglob
    
por 06.01.2017 / 23:30
12

Este comando mostrará todos os não diretórios em / :

find / -maxdepth 1 -type f

Depois de ter absolutamente a certeza de que não existem ficheiros que pretenda manter, pode utilizar:

find / -maxdepth 1 -type f -delete

Mais seguro, seria movê-los para outro lugar para garantir que você não esteja excluindo algo que deseja preservar:

mkdir /root/preserve
find / -maxdepth 1 -type f -exec mv -- "{}" /root/preserve/\;

Se, além dos arquivos, você também tiver diretórios adicionados à raiz do sistema de arquivos, isso poderia ser automatizado excluindo os diretórios do LSB de um mv ou rm automatizado, mas honestamente, como estamos lidando com a limpeza de itens na raiz do sistema de arquivos, sugiro strongmente que você considere fazê-lo manualmente, se possível.

Se isso não for viável, algo assim poderia resolver o problema:

#!/bin/bash
declare -a excludes
for item in root sys 'lost+found' mnt home proc etc opt boot lib lib64 libx32 sbin media srv dev var usr bin tmp run; do
    excludes+=("$item")
done
if ! [[ -d /root/preserve ]]; then
    mkdir -p /root/preserve
fi
IFS="\n"
for item in find / -type d -maxdepth 1; do
    really=true
    for exclude in ${excludes[@]}; do
        if [[ "$exclude" == "${item#/}" ]]; then
            really=false
        fi
    done
    if [[ "true" == "$really" ]]; then
        mv -- "$item" /root/preserve/
    fi
done

Depois de passar no teste de grito (ou seja, seu sistema ainda funciona e você não está gritando de angústia), é possível remover o conteúdo de /root/preserve/ .

Nota importante: faça o que fizer, nem pense em executar qualquer permutação de rm -fr [ANYTHING GOES HERE] / .

    
por 06.01.2017 / 22:22
3

Isso deve fazer o trabalho (embora não da mesma forma que o OP pergunta):

ls -1 >1.txt
pico 1.txt 

remova todos os arquivos / diretórios que deseja manter

xargs rm < 1.txt

Se todos os seus arquivos tiverem o mesmo formato de nome, data ou outra coisa, existem outros métodos.

Eu olhei para os inodes - e veja se eles são seqüenciais via ls -i | sort e se eles são, então os novos arquivos terão inodes maiores. Em seguida, usando o mesmo tipo de processo acima ...

ls -iF1 | sort |cut -c10- | grep -vE "\/|\@" >i.txt   #This part removes entries that are not regular files, such as directories and links.  
pico i.txt
xargs rm < i.txt

no comando de corte acima, verifique sua lista de inodes primeiro para ter certeza de que é a quantidade certa.

    
por 06.01.2017 / 22:20