Me sorprendió recientemente cuando hice algo así
mv ./* ../somedirectory
y descubrí que los archivos como .gitignoreno se movían.
Hago la mayor parte de mi trabajo en zsh en OS X, y esta sorpresa me mordió en bash en CentOS. Intenté bash en OS X y encontré el mismo comportamiento: *no coincide con los archivos de puntos. Esto me parece muy indeseable, pero aparentemente es el bash predeterminado. (Puede que también sea el valor predeterminado de zsh para todo lo que recuerdo, pero puede que lo haya cambiado hace años en mi .zshrc y olvidado que alguna vez funcionó de manera diferente).
¿Cómo puedo configurar bash para que se comporte como esperaba ?: * para que coincida con todos los archivos y no ignore los archivos de puntos.
En caso de que esto no esté del todo claro, he aquí cómo reproducirlo
cd /tmp
mkdir {t,d}est
touch test/{.,}{1,2,3,4,5,6,7}
ls -hal test
mv test/* dest
ls -hal test # notice dot files are still there
ls -hal dest # notice only some files were mv'ed

Respuestas:
Golpetazo
Como ya notó, bash no coincidirá con un
.al comienzo del nombre o una barra inclinada. Para cambiar la coincidencia con respecto al punto, debe configurar ladotglobopción - man bash :dotglob Si está configurado, bash incluye nombres de archivo que comienzan con un '.' en Los resultados de la expansión del nombre de ruta.Para habilitarlo / configurarlo con bash use
shopt, por ejemplo:Para zsh también puede usar la
dotglobopción, pero deberá usarlasetoptpara habilitarla, por ejemplo:fuente
zsh, la mejor opción es habilitar dotglob por globo:mv test/*(D) /destProbé esto y resuelve el problema:
Salida:
fuente
*es un globo que se expande por el caparazón. De manera predeterminada, los shells no incluyen archivos cuyo nombre comience con un.(llamados archivos ocultos o archivos de puntos) a menos que el encabezado.se ingrese literalmente.*o[.]*o?*o*.*odir/*no incluirán archivos de puntos..*o lodir/.*haré.Entonces podrías hacer:
sin embargo, algunos shells que incluyen
bash(pero nozsh,mkshnifish) tienen la característica errónea de que la expansión de.*incluir las entradas de directorio especiales.y.., que no desea aquí (y generalmente nunca quiere que se incluya un globo, es por eso que lo llamo una característica incorrecta).Por esa razón, encontrará que a veces las personas usan (en conchas tipo Bourne):
Esos son tres globos, el primero coincide con archivos no ocultos, el segundo nombre de archivo comienza con
.seguido de un carácter diferente.y el tercero nombres de archivo comienzan con..seguido de al menos un carácter.Sin embargo, algunos proyectiles modernos tienen mejores formas de evitar eso
zsh
Con
zsh, puede usar el(D)calificador glob para especificar que el glob debe incluir archivos de puntos:zshTambién se corrigió esa otra falla del shell Bourne en que si el patrón no coincide, elmvcomando no se ejecuta.Como se dijo anteriormente, nunca incluirá
.ni..en sus globos, por lo queserá segura. Sin embargo, si no hay coincidencia de archivos
*o no coincide.*el archivo, el comando se cancelará, por lo que sería mejor usar:Al igual que en otros shells, también puede obligar a todos los globos a incluir archivos de puntos (por ejemplo, si desea que los archivos de puntos se incluyan con mayor frecuencia) con:
o:
Después de eso, si desea que un globo en particular no incluya archivos de puntos, puede escribirlo:
O:
Golpetazo
Lamentablemente
bashno tiene calificadores globales. Por lo tanto, le queda habilitar la inclusión de archivos de puntos a nivel mundial. Enbash, la sintaxis es:(y usar
[^.]*para globos sin archivos ocultos).Con
dotglob,bashno incluye.ni..en globos como*, pero todavía lo hace para globos como.*.Si establece la
GLOBIGNOREvariable en algo que no esté vacío, entonces habilita automáticamente ladotglobopción y excluye.y..de los.*globos pero no dedir/.*o.*/fileunos (!) Para que la protección sea bastante inútil. Podrías hacerlo,GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'pero luego rompería globos como*/.o./*o../*.Una mejor en torno al trabajo es utilizar
[.]*odir/[.]*o[.]*/file(condotglobactivado) para ampliar dotfiles excepción.y...pez
fishlos globos no incluyen.ni... Cuando no hay coincidencia, dependiendo de la versión, funcionará comozsh(obash -o failglob) obash -o nullglob.Funcionaría si hay archivos ocultos y no ocultos. De lo contrario, YMMV y con algunas versiones, puede llamar
mv -- /destsi no hay ningún archivo.ksh93
No hay calificador global en
ksh93ninguno de los dos. Puede incluir archivos de puntos en globos con:Al contrario de
bashs'GLOBIGNORE, que se ha hecho correctamente y también corrige el problema de.*que incluye.y...yash
yashtiene unadot-globopción (set -o dot-glob), pero al contrariobash, las expansiones globales (incluso de*) incluyen.y,..por lo tanto, es bastante inútil.tcsh
Funciona como en
bash, es decir,*incluye archivos de puntos excepto.y..pero.*aún incluye.y..(y puede usar[.]*para expandir archivos ocultos excepto.y..).fuente
La forma más fácil en bash para imprimir archivos de puntos coincidentes, ignorando
.y..es:Probar:
Imprimió todos los archivos con puntos o no, con la notable excepción de
.y...Su ejemplo también funcionará correctamente:
Vacío de archivos que importan.
Los archivos del sistema
...todavía existen, pero una expansión de shell (usando *) no los incluirá.Y el dest directorio minación contiene todos los archivos:
¿Por qué?
Esto funciona porque el establecimiento GLOBIGNORE tiene esta secundarios efectos:
shopt -s dotglob) en archivos de puntos matemáticos en expansiones..y..se ignoran cuando GLOBIGNORE está configurado y no es nulo.Los detalles en el manual:
LESS=+'/The GLOBIGNORE' man bash.Además, debemos configurar la variable GLOBIGNORE para que contenga un nombre que ningún nombre de archivo pueda coincidir:
una barra oblicua (y algo más como una doble precaución).
Puede ser útil configurar también nullglob si es necesario para evitar obtener un
*cuando no hay un archivo que coincida con el*.fuente
Muy interesado en esta configuración de GLOBIGNORE = / + / @ user79743
Desde mi experiencia, desestabilizar dotglob es un mal negocio para casi todos sus comandos (cp, mv, etc.) PERO lo mismo es cierto establecer el nullglob (¡especialmente con expresiones regulares que luego necesitan escapar!).
Sin embargo, si necesita establecerlos al comienzo de su programa pero interferir en partes específicas donde llama a comandos como cp, mv, etc. o usa expresiones regulares, simplemente haga esto:
fuente