O que significa. ?? * em um comando shell?

22

O comando a seguir irá tar"pontilhar" arquivos e pastas:

tar -zcvf dotfiles.tar.gz .??*

Eu estou familiarizado com expressões regulares , mas não entendo como interpretar .??*. I executada ls .??*e tree .??*e olhou para os arquivos que foram listados. Por que essa expressão regular inclui todos os arquivos em pastas que começam com, .por exemplo?

SabreWolfy
fonte

Respostas:

32

Globs não são expressões regulares. Em geral, o shell tentará interpretar qualquer coisa que você digitar na linha de comando que você não citar como um globo. Os shells não são necessários para suportar expressões regulares (embora, na realidade, muitos dos mais modernos e extravagantes o façam, por exemplo, o =~operador de correspondência de expressões regulares na bash [[construção).

O .??*é um globo. Corresponde a qualquer nome de arquivo que comece com um ponto literal ., seguido por dois caracteres (não necessariamente o mesmo) ??, seguido pela expressão regular equivalente a [^/]*, ou seja, 0 ou mais caracteres que não são /.

Para obter detalhes completos sobre a expansão do nome do caminho do shell (o nome completo para "globbing"), consulte a especificação POSIX .

jw013
fonte
10
Ponto adicional: esta é uma tentativa de escrever um globo que corresponda a todos os arquivos de ponto em um diretório, exceto as entradas especiais .e com as ..quais normalmente não se deseja fazer nada. Não está certo; ele não pega nada chamado ' .X' onde X é algum caractere que não seja ponto. Eu não acho que é possível escrever um único globo que corresponda a todos os arquivos de pontos, exceto .e .., mas você pode fazer isso com dois: tar zcvf dotfiles.tar.gz .[!.] .??*por exemplo.
Zwol 22/07/12
@ Zack: Obrigado pelo esclarecimento. Publiquei um comentário sobre isso, mas o excluí. ls .?retornou o mesmo que ls .., o que significava que não havia outras entradas na pasta que correspondessem ao padrão .?. Eu teria feito .[^.]para todos os .?arquivos que não sejam ...
SabreWolfy
2
@SabreWolfy Se você ler atentamente a especificação POSIX, essa é realmente uma diferença importante entre globs e regex: nas expressões entre colchetes, [^abc]na sintaxe regex significa o mesmo que [!abc]na sintaxe glob (ou ^seja, substituída !por globs). O uso da [^abc]sintaxe de estilo em um globo não é muito portátil, porque o POSIX não especifica o que significa, portanto, alguns shells o interpretam usando semântica do tipo regex, enquanto outros tratam ^apenas como um caractere literal.
Jw013
1
@ jw013: Obrigado pelos detalhes. Devo lembrar que glob = regexp :)!
SabreWolfy
1
Apenas me ocorreu que .[!.]pode ser deixado como um literal na tarlinha de comando no caso comum em que não há arquivos que correspondam a esse padrão. Alguns shells permitem controlar esse comportamento, por exemplo, com o bash, shopt -s nullglobo fará desaparecer da linha de comando se não corresponder a nada, mas isso não é um recurso universal.
zwol 23/07/12
8

O .??*curinga ( não uma expressão regular, embora pareça assim) se traduz em nomes de arquivos que começam com um ponto ( .), seguidos por dois caracteres únicos ( ??) e, em seguida, qualquer número (zero ou mais) de outros caracteres ( *).

Talvez esta página de caracteres curinga nos nomes de arquivos seja útil.

Levon
fonte
-1

Para adicionar às outras respostas, um único ?será convertido em um único nome de arquivo de caractere e ??corresponderá a nomes de arquivos que possuem apenas dois caracteres e assim por diante.

[root@mercy testdir_2]# ls
ion  it  r
[root@mercy  testdir_2]# ls ?
r
[root@mercy  testdir_2]# ls ??
it
[root@mercy 1 testdir_2]# ls ???
ion
[root@mercy  testdir_2]#
Sree
fonte
Downvoter, você poderia comentar por favor? Ficaria feliz em ser corrigido, se eu estiver errado.
Sree 26/03
Sua resposta não respondeu totalmente à pergunta.
SabreWolfy