Me sorprendió recientemente cuando hice algo así
mv ./* ../somedirectory
y descubrí que los archivos como .gitignore
no 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 ladotglob
opción - man bash :Para habilitarlo / configurarlo con bash use
shopt
, por ejemplo:Para zsh también puede usar la
dotglob
opción, pero deberá usarlasetopt
para habilitarla, por ejemplo:fuente
zsh
, la mejor opción es habilitar dotglob por globo:mv test/*(D) /dest
Probé 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
,mksh
nifish
) 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:zsh
También se corrigió esa otra falla del shell Bourne en que si el patrón no coincide, elmv
comando 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
bash
no 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
,bash
no incluye.
ni..
en globos como*
, pero todavía lo hace para globos como.*
.Si establece la
GLOBIGNORE
variable en algo que no esté vacío, entonces habilita automáticamente ladotglob
opción y excluye.
y..
de los.*
globos pero no dedir/.*
o.*/file
unos (!) 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
(condotglob
activado) para ampliar dotfiles excepción.
y..
.pez
fish
los 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 -- /dest
si no hay ningún archivo.ksh93
No hay calificador global en
ksh93
ninguno de los dos. Puede incluir archivos de puntos en globos con:Al contrario de
bash
s'GLOBIGNORE
, que se ha hecho correctamente y también corrige el problema de.*
que incluye.
y..
.yash
yash
tiene unadot-glob
opció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