Como posso fazer com que o bash não corresponda a `.` e `..` com `.*`

Como posso fazer com que o bash não corresponda a `.` e `..` com `.*`

Quando tento combinar todos os arquivos de ponto em um diretório, .*parece haver um efeito colateral desagradável: além de combinar todos os arquivos e diretórios (reais), ele corresponde .e ...

bash-3.2$ mv test/.* dest/
mv: rename test/. to dest/.: Invalid argument
mv: test/.. and dest/.. are identical

Isso parece muito estranho, já que eles são basicamente diretórios 'falsos', apenas para facilitar os caminhos relativos. Eles não fazem parte do conteúdo de um diretório e nunca quero que sejam correspondidos quando tento mover o conteúdo de um diretório para outro. Não consigo pensar em nenhum cenário em que eu gostaria que eles fossem correspondidos .*.

Então, como posso desligar isso? (Além de usar o shell Z, que nem sempre está disponível e que pode não ser o shell usado por alguém que executa uma função que escrevi.)

Responder1

Você pode usar a GLOBIGNOREvariável bash.

       GLOBIGNOR
              Uma lista de padrões separados por dois pontos que definem o conjunto de nomes de arquivos
              a ser ignorado pela expansão do nome do caminho. Se um nome de arquivo corresponder a um
              padrão de expansão do nome do caminho também corresponde a um dos padrões em
              GLOBIGNORE, é retirado da lista de partidas.

e

       .......................... Os nomes dos arquivos ``.'' e ``..'' são sempre
       ignorado quando GLOBIGNORE está definido e não é nulo.  

Então, se você definir

GLOBIGNORE='*/.:*/..'

then path/.*não corresponderá .a and .., como você pergunta.

Responder2

Um padrão glob seria .[^.]*- corresponde a algo com pelo menos 2 caracteres onde o segundo caractere não é um ponto.

A documentação para correspondência de padrões de nome de arquivo está na página de manual do bash ou aqui:http://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching


Jonathan Callen levanta um bom ponto. Você pode usar um padrão estendido bastante simples

shopt -s extglob
ls -d .!(.|)

informação relacionada