Como apagar tudo, exceto os diretórios numéricos de nível superior?

4

Eu quero excluir tudo em algum diretório /path/to/foo , EXCETO os subdiretórios que correspondem ao meta-padrão

/path/to/foo/<DIGITS>/

Por exemplo, se o conteúdo em /path/to/foo for inicialmente assim:

/path/to/foo
├── 0/
│   ├── a
│   └── b
├── 232532/
├── 42
├── 73/
│   ├── d
│   └── e
├── 8xyz/
│   ├── i
│   └── j
├── _bar/
│   ├── x
│   ├── y
│   └── z
├── .baz/
│   ├── f
│   └── frobozz/
│       ├── g
│       └── h
└── quux/
    └── 123/

... eu quero acabar com

/path/to/foo
├── 0/
│   ├── a
│   └── b
├── 232532/
└── 73/
    ├── d
    └── e

Estou à procura de um encantamento baseado em find ... -delete ou de um padrão% glob dezsh adequado (para rm -r ), que fará isso. Eu estou usando o Linux.

    
por kjo 08.08.2017 / 18:22

5 respostas

5

com zsh :

set -o extendedglob # best in ~/.zshrc
rm -rf /path/to/foo/^<->(D) /path/to/foo/<->(^-/)
  • ^something is não é algo (semelhante a ksh 's !(something) )
  • <-> é <x-y> para corresponder a números inteiros decimais de x a y , mas sem nenhum dos limites fornecidos (portanto, corresponde a qualquer sequência de dígitos decimais, semelhante a ksh ' +([0-9]) ).
  • (D) um qualificador de glob para incluir arquivos ocultos ( D ot files)
  • (^-/) um qualificador de glob para dizer apenas arquivos que não são do tipo directory após a resolução do symlink (remova o - se você também quiser remover links simbólicos para os diretórios).
por 08.08.2017 / 18:46
4

Se você tiver acesso ao GNU find , poderá executar:

find . -maxdepth 1 -not \( -type d -regex '.*/[0-9]*$' \) -exec rm -r {} +

A idéia é encontrar os arquivos de nível superior que não sejam i) diretórios e ii) cujo nome não consista em nada além de números.

Recomendamos enfaticamente que você o execute uma vez com echo em vez de rm -r para ver o que ele fará.

    
por 08.08.2017 / 18:46
4
cd /path/to/foo && \
find . -maxdepth 1 ! -type d -delete -o \
   ! -name . -name '*[!0-9]*' -exec rm -rf {} +

Qual lê como:

  • mude para o diretório / path / to / foo e, assim que tiver êxito,
  • invoque find para ir apenas a um nível de profundidade e exclua todos os diretórios não existentes.
  • para todos os outros, ou seja, subdiretórios no diretório / path / to / foo, rejeitar aqueles com os nomes "." e o que resta deles, selecione aqueles que tenham pelo menos um não-dígito.
  • Os diretórios selecionados são direcionados para o abbatoir, garantindo assim a sobrevivência dos diretórios somente de dígitos.
por 08.08.2017 / 18:50
3

Além do zsh , você não pode selecionar não-diretórios usando curingas (você só pode aplicar um padrão curinga para todos os tipos de arquivo, ou se aplicam a diretórios e links simbólicos para diretórios colocando um / no final).

Em qualquer shell, você pode fazer um loop pelos arquivos e excluir os que deseja manter. Para enumerar todos os arquivos, incluindo arquivos de ponto e . e .. , use os dois padrões curinga * .* . É possível que * não corresponda a nenhum arquivo e assim permanecerá não expandido; Nesse caso, rm -rf é executado em * , o que não faz nada, pois rm -f ignora argumentos inexistentes.

for x in * .*; do
  case "$x" in
    .|..: continue;;                              # skip the . and .. entries
    *[!0-9]*) rm -rf -- "$x";;                    # not just digits -> delete
    *) if ! [ -d "$x" ]; then rm -f -- "$x"; fi   # just digits -> delete if not a directory
  esac
done
    
por 09.08.2017 / 01:07
1
find ./* ! \( -type d -regex "./[0-9]+\(/.*\)?" \) -delete

ou, se foo tiver arquivos demais e o excesso de limite de argumento ocorrer, use:

find . ! -path . ! \( -type d -regex "./[0-9]+\(/.*\)?" \) -delete
    
por 08.08.2017 / 20:20