Como faço para combinar apenas dotfiles no bash? [duplicado]

2

rm -rf .* só não será finalizado porque rm se recusa a excluir . e .. .

Como excluo esses diretórios especiais de um padrão glob?

Isso não é resolvido por dotglob , pois quero corresponder apenas os arquivos que começam com um ponto e não todos os arquivos.

    
por Franklin 18.10.2018 / 11:23

6 respostas

2

Com o bash, a configuração da variável GLOBIGNORE special é um valor não vazio que é suficiente para ignorar . e .. ao expandir globs. De os documentos do Bash :

The GLOBIGNORE shell variable may be used to restrict the set of filenames matching a pattern. If GLOBIGNORE is set, each matching filename that also matches one of the patterns in GLOBIGNORE is removed from the list of matches. If the nocaseglob option is set, the matching against the patterns in GLOBIGNORE is performed without regard to case. The filenames . and .. are always ignored when GLOBIGNORE is set and not null. However, setting GLOBIGNORE to a non-null value has the effect of enabling the dotglob shell option, so all other filenames beginning with a ‘.’ will match.

Se o definirmos como .:.. , tanto . como .. serão ignorados. Como configurá-lo para qualquer coisa não-nula também obterá esse comportamento, podemos defini-lo como apenas .

Então:

GLOBIGNORE=.
rm -rf .*

(De minha resposta anterior em Ask Ubuntu .)

    
por 18.10.2018 / 12:00
4

Isso deve ser feito:

rm -rf .[^.] .??*  

Este comando pode capturar todos os casos.

.[^.] irá capturar quaisquer entradas de dois caracteres. .??* irá corresponder apenas a 3 + nomes de caracteres.

    
por 18.10.2018 / 11:29
1

Você precisa excluir pontos únicos e duplos:

rm -rf {..?,.[!.]}*
  • ..?* combina tudo com dois pontos seguidos de qualquer coisa
  • .[!.]* combina tudo com um único ponto não seguido por outro ponto
por 18.10.2018 / 11:29
1

com extglob :

$ shopt -s extglob
$ touch ... .a .bbb ..c foo
$ echo .!(.|)
... .a .bbb ..c

!(.|) corresponde a qualquer coisa, menos a um ponto ou está vazio, por isso .!(.|) corresponde a qualquer coisa que comece com um ponto, exceto . e .. .

    
por 18.10.2018 / 11:34
1

@Goro tem, eu acho, a resposta mais simples e totalmente correta. No entanto, acho que é difícil digitar. Eu sugeriria em vez disso

ls .??*

É absolutamente verdade que isso perderá arquivos como .a , mas eles são tão extraordinariamente raros que, na prática, não acho que seja importante, especialmente para uso interativo.

    
por 18.10.2018 / 11:50
1

Com find , é um pouco mais para digitar, mas você pode ser mais explícito, o que facilita o entendimento:

find . -maxdepth 1 -name '.*' ! -name . ! -name .. -exec rm -rf {} +

Isso chama rm -rf com todos os nomes no diretório atual (somente) que começa com um ponto e que não é . nem .. . Eu não estou usando -delete aqui, pois esse predicado pode não excluir diretórios não vazios.

Se você deseja corresponder apenas aos arquivos regulares no diretório atual, fica ainda mais fácil:

find . -maxdepth 1 -type f -name '.*' -delete

Aqui, não precisamos excluir . ou .. , pois eles são excluídos automaticamente por -type f .

Altere -type f para ! -type d para excluir qualquer diretório diferente (isto é, links simbólicos, etc.)

    
por 18.10.2018 / 11:59