¿Qué significa. ?? * en un comando de shell?

22

El siguiente comando tar"archivará" todos los archivos y carpetas:

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

Estoy familiarizado con las expresiones regulares , pero no entiendo cómo interpretar .??*. Ejecuté ls .??*y tree .??*miré los archivos que estaban en la lista. ¿Por qué esta expresión regular incluye todos los archivos dentro de carpetas que comienzan .por ejemplo?

SabreWolfy
fuente

Respuestas:

32

Los globos no son expresiones regulares. En general, el shell intentará interpretar cualquier cosa que escriba en la línea de comando que no cita como un globo. No es necesario que los shells admitan expresiones regulares (aunque en realidad muchos de los más modernos y sofisticados sí lo hacen, por ejemplo, el =~operador de coincidencia de expresiones regulares en la bash [[construcción).

El .??*es un pegote. Coincide con cualquier nombre de archivo que comience con un punto literal ., seguido de dos caracteres (no necesariamente el mismo) ??, seguido del equivalente de expresión regular de [^/]*, es decir, 0 o más caracteres que no lo son /.

Para conocer todos los detalles de la expansión del nombre de ruta del shell (el nombre completo de "globbing"), consulte la especificación POSIX .

jw013
fuente
10
Punto adicional: este es un intento de escribir un globo que coincida con todos los archivos de puntos en un directorio, excepto las entradas especiales .y con el ..que normalmente no se quiere hacer nada. No está del todo bien; no recoge nada llamado ' .X' donde X es un personaje que no sea punto. No creo que sea posible escribir un solo globo que coincida con cada archivo de puntos excepto .y .., pero puede hacerlo con dos: tar zcvf dotfiles.tar.gz .[!.] .??*por ejemplo.
zwol
@Zack: Gracias por la aclaración. Publiqué un comentario al respecto, pero luego lo eliminé. ls .?devolvió lo mismo que ls .., lo que significa que no había otras entradas en la carpeta que coincidan con el patrón .?. Lo hubiera hecho .[^.]para todos los .?archivos que no sean ...
SabreWolfy
2
@SabreWolfy Si lee detenidamente la especificación POSIX, esa es realmente una diferencia importante entre globs y regex: en las expresiones de corchetes, [^abc]en la sintaxis regex significa lo mismo que [!abc]en la sintaxis glob ( ^es decir, se reemplaza !por globs). El uso de la [^abc]sintaxis de estilo en un globo no es muy portátil porque POSIX no especifica lo que significa, por lo que algunos shells lo interpretan utilizando una semántica similar a la expresión regular, mientras que otros lo tratan ^como un carácter literal.
jw013
1
@ jw013: Gracias por los detalles. Debo recordar ese glob! =
Regexp
1
Se me ocurrió que .[!.]puede dejarse como un literal en la tarlínea de comando en el caso común donde no hay archivos que coincidan con ese patrón. Algunos shells le permiten controlar ese comportamiento, por ejemplo, con bash, shopt -s nullgloblo hará desaparecer de la línea de comando si no coincide con nada, pero esa no es una característica universal.
zwol
8

El .??*comodín ( no es una expresión regular, aunque se ve de esa manera) se traduce en nombres de archivo que comienzan con un punto ( .), seguidos de dos caracteres individuales ( ??) y luego cualquier número (cero o más) de otros caracteres ( *).

Tal vez esta página sobre comodines en nombres de archivo sea ​​útil.

Levon
fuente
-1

Para agregar a las otras respuestas, un solo ?se traducirá a un nombre de archivo de un solo carácter y ??coincidirá con los nombres de archivo que solo tienen dos caracteres, etc.

[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
fuente
Downvoter, ¿podrías comentar por favor? Estaría encantado de ser corregido, si estoy equivocado.
Sree
Su respuesta no respondió la pregunta completamente.
SabreWolfy