2010-05-26 11 views
28

Muchas veces quiero ejecutar un comando en todos los archivos (incluidos los ocultos) en un directorio. Cuando intento usarCómo usar el comodín. * En bash pero excluir el directorio padre (..)?

chmod g+w * .* 

cambia los permisos de todos los archivos que desea (en el directorio) y todos los archivos en el directorio padre (que yo quiero no hacer nada).

¿Hay algún comodín que haga lo correcto o debo comenzar a utilizar find?

Respuesta

37

Se necesitan dos patrones globales para cubrir todos los posibles “archivos punto”: .[^.]* y ..?*.

La primera coincide con todas las entradas de directorio con dos o más caracteres donde el primer carácter es un punto y el segundo carácter no es un punto. El segundo recoge entradas con tres o más caracteres que comienzan con .. (esto excluye .. porque solo tiene dos caracteres y comienza con ., pero incluye entradas (poco probables) como ..foo).

chmod g+w .[^.]* ..?* 

Esto debería funcionar bien en la mayoría de las conchas y es adecuado para las secuencias de comandos.


Para el uso interactivo regular, los patrones pueden ser demasiado difíciles de recordar. En esos casos, su caparazón podría tener una forma más conveniente de omitir . y ... zsh siempre excluye . y .. de patrones como .*. Con bash, debe usar la variable de shell GLOBIGNORE.

# bash 
GLOBIGNORE=.:.. 
echo .* 

quizás debería definir GLOBIGNORE en una de sus de bash archivos de personalización (por ejemplo .bash_profile/o .bash_login.bashrc). Tenga cuidado, sin embargo, acostumbrarse a esta personalización si a menudo usa otros entornos. Si ejecuta un comando como chmod g+w .* en un entorno al que le falta su personalización, inesperadamente terminará incluyendo . y .. en su comando.

Además, se pueden configurar las conchas para incluir archivos “punto” en los patrones que no empiezan con un punto explícita (por ejemplo *).

# zsh 
setopt glob_dots 

# bash 
shopt -s dotglob 


# show all files, even “dot files” 
echo * 
+5

En realidad, ese GLOBIGNORE es bueno. Puedes hacerlo temporalmente con '(GLOBIGNORE = ..; echo. *)' Si no quieres que sea permanente. +1 por esa pequeña información solo. – paxdiablo

+5

Existe una advertencia con el englobador '. [^.] * ..? *' Donde generalmente se quejará de que no coinciden las partes ...? *, A menos que compre nullglob. – pixelbeat

2

Normalmente solo usaría . .[a-zA-Z0-9]* ya que mis nombres de archivo tienden a seguir ciertas reglas, pero eso no detectará todos los casos posibles.

Usted puede uso:

chmod g+w $(ls -1a | grep -v '^..$') 

que será básicamente una lista de todos los archivos y directorios, pelar hacia fuera el directorio padre y luego procesar el resto. Sin embargo, tenga cuidado con los espacios en los nombres de archivos, los tratará como archivos separados.

Por supuesto, si lo que desea es hacer archivos, puede utilizar:

find . -maxdepth 0 -type f -exec chmod g+w {} ';' 

o, sin embargo, otra solución, que debe hacer todos los archivos y directorios, excepto el .. uno:

for i in * .* ; do if [[ ${i} != ".." ]] ; then chmod g+w "$i"; fi done 

pero ahora ingresa al territorio donde pueden ser necesarios scripts o alias.

+0

simplemente retire el -v grep '^ $.' Desde Allan quiere los archivos ocultos, pero no la carpeta principal –

1

¿Qué tal:

shopt -s dotglob 
chmod g+w ./* 
1

Puesto que no se puede configurar dotglob para el resto de su sesión de bash se puede configurar para un único conjunto de comandos mediante la ejecución de un subproceso de este modo:

$ (shopt -s dotglob; chmod g+w ./*) 
2

lo que hice fue

tar --directory my_directory --file my_directory.tar --create `ls -A mydirectory/` 

Funciona bien el ls -A my_directory se expande a todo en el directorio excepto . y ... Sin globos engorrosos, y en una sola línea.

ps: Quizás alguien me diga por qué no es una buena idea. : P

+0

Sí, funciona bien (la opción 'Casi todos' en ls, sin embargo, para hacerlo ahora está comenzando otro proceso, en este caso/bin/ls ... normalmente no es una mala idea, sin embargo, si está trabajando con dig 10 000 + directorios, puede comenzar a tomar un poco de recursos un poco - globbing es hecho por el shell y no inicia ningún proceso para llegar a la lista, y realmente la mayoría de la gente puede salirse con la suya simplemente usando *. [^. ] * que básicamente se ve como un hombre calvo con un monóculo, por lo que era fácil de recordar (además es bastante similar a regex, ¿no todos saben regex por ahora? o estoy fuera de lugar aquí> :) – osirisgothra

+1

Esto falla si los nombres de archivo contienen espacios. –

0

Si está seguro de que no se utilizarán dos caracteres nombres de archivo oculto, a continuación, la opción más sencilla es simplemente ser hacer:

chmod g+w * ...* 
Cuestiones relacionadas