Apagar pastas cujo nome tenha números de 4 dígitos duas vezes

5

Eu quero excluir pastas usando regexp em um terminal Mac.

0129_0140 (no delete)
0140_0140 (delete)
0150_0160 (no delete)
0170_0170 (delete)

Eu só quero excluir pastas como 0140_0140, 0170_0170.

(adicionado) Eu quero excluir as pastas não vazias, recursivamente.

    
por jakeoung 10.02.2016 / 11:15

4 respostas

12

Não recursivo

Com ksh93 (no OS / X disponível como ksh ):

rmdir {4}(\d)_

(cuidado, pode deletar um diretório chamado {4}(\d)_ se não houver um arquivo que corresponda a esse padrão).

Com zsh (no OS / X disponível como zsh ):

setopt extendedglob
rmdir [0-9](#c4)_[0-9]##(/e:'[[ ${REPLY%_*} = ${REPLY#*_} ]]':)

(esse também tem o benefício de considerar apenas arquivos do tipo diretório , usando o qualificador / glob acima).

Com bash ou outro shell POSIX (como sh da maioria dos sistemas, incluindo OS/X ):

set -- [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]
for f do
  [ "${f#*_}" = "${f%_*}" ] && set -- "$@" "$f"
  shift
done
rmdir "$@"

(cuidado, ele pode excluir um diretório chamado [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9] se não houver arquivos XXXX_XXXX no diretório atual).

Usando find e grep :

find . ! -name . -prune -type d -name '[0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]' |
  grep -x '\./\(.*\)_' |
  xargs rmdir

Com BSD find (como encontrado no OS / X):

find . -maxdepth 1 -regex './\([0-9]\{4\}\)_' -type d -delete

Com o GNU find (normalmente não encontrado no OS / X, a menos que seja instalado via macports / homebrew / fink ...):

find . -maxdepth 1 -regextype grep -regex './\([0-9]\{4\}\)_' -type d -delete

Recursivamente:

  • ksh93 :

    set -o globstar
    rmdir -- **/{4}(\d)
    

    (lembre-se de que não removerá 1111_1111 caso haja um 1111_1111/2222_2222 , pois ele tentará remover o 1111_1111 primeiro, o que não é possível, pois há 2222_2222 dir nele, ksh93 não tem o qualificador od glob (para primeira ordem de profundidade) de zsh )

  • zsh :

    setopt extendedglob
    rmdir -- **/[0-9](#c4)_[0-9]##(Dod/e@'[[ ${${REPLY:t}%_*} = ${REPLY##*_} ]]'@)
    
  • BSD find :

    LC_ALL=C find . -regex '.*/\([0-9]\{4\}\)_' -type d -delete
    
  • GNU find :

    LC_ALL=C find . -regextype grep -regex '.*/\([0-9]\{4\}\)_' -type d -delete
    
por 10.02.2016 / 11:19
2

POSIX (remova echo de echo rmdir para realmente apagar os arquivos):

for dir in [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]/; do
    a="$(expr "$dir" : '\(.*\)_/')"
    ${a:+false} || echo rmdir "$dir"
done

Ou:

for d in [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]/; do
    expr "$d" : '\(\(.*\)_\)/' >/dev/null && echo rmdir "$d"
done

Ou:

set -- [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]/
for    d
do     expr "$d" : '\(\(.*\)_\)/' >/dev/null && echo rmdir "$d"
done
    
por 10.02.2016 / 12:17
1

Tente isto:

find -type d -regextype posix-extended -regex '\./([0-9]{4})_' -delete

A configuração do tipo regex é necessária para o {4} .

    
por 10.02.2016 / 11:30
1

Um par de alternativas simples compatíveis com POSIX:

Não recursivo (novas linhas não permitidas no nome da base):

ls -F | grep '^\([0-9]\{4\}\)_/$' | xargs rm -fr

Recursivo:

find . -type d -exec expr {} : '.*/\([0-9]\{4\}\)_$' \; -prune \
       -exec rm -fr {} + >/dev/null
    
por 11.02.2016 / 09:29