2011-01-26 15 views
5

he encontrado la siguiente secuencia de comandos en commandlinefu.com (el ejemplo no es en línea más):¿Cómo funciona esta función bash para eliminar todos los archivos, excepto algunos?

rmbut() { 
    local x=("[email protected]") 
    IFS=, rm -rf *[!"${x[*]}"] 
} 

Se elimina todos los archivos y directorios, pero los nombrados en la línea de comandos.

Podría explicar lo siguiente:

  • Lo que está sucediendo en la primera línea? [email protected] significa todos los argumentos, pero ¿por qué se pone entre paréntesis?
  • He leído sobre IFS pero nunca lo he usado, ¿cuál es su uso aquí?
  • ¿Qué se logra con *[!"${x[*]}"]? No puedo entender cómo dividirlo en algo que sé.
+0

¿Estás seguro de que son paréntesis() en la línea "local x .." o son llaves {} o corchetes []. Hace una diferencia. Además, desde el aspecto de la función, simplemente se eliminan todos los archivos excepto los que tienen los nombres básicos especificados por los parámetros para la función. – kvista

+0

Sí, los paréntesis son correctos. Ese es el propósito de la función, eso está claro, me gustaría saber por qué ^^ –

Respuesta

4

local x=("[email protected]") crea una matriz que es una copia de todos los argumentos ([email protected] es en sí misma una matriz).

IFS=, establece el separador de campo interno en una coma.

IFS=, rm -rf *[!"${x[*]}"] dice eliminar todos los archivos que no terminan en ningún carácter pasado como argumentos. Como * se utiliza como el índice de la matriz y la variable se cita, se expande a una sola cadena y los espacios que normalmente separarían los elementos de la matriz se reemplazan por los contenidos de IFS (una coma en este caso).

rmbut a b c 

resuelve a rm -rf *[!a,b,c] que tampoco sería eliminar los archivos que terminan en una coma.

I piensan la función podría simplificarse a:

rmbut() { 
    IFS= rm -rf *[!"$*"] 
} 

pero su comportamiento sería sutilmente diferente. Esta versión establece IFS a null por lo que el ejemplo anterior resolvería a rm -rf *[!abc] que sería eliminar archivos que terminan en una coma (una coma tendría que ser pasado explícitamente como un argumento para preservar dichos archivos). Sin embargo, ese comportamiento podría devolverse configurando IFS=, (simplemente no es necesario copiar la matriz).

+0

Gracias por la respuesta detallada :) –

3

# crear una matriz x, que contiene argumentos de la función
local x=("[email protected]")

# unset la variable IFS. Esto hace que las matrices de doble citados se expanden a palabras sueltas w/o separadores
IFS=

# eliminan archivos que coinciden con un patrón, es decir, no termina con un carácter de la matriz x
rm -rf *[!"${x[*]}"]

+0

@eugene y: Usted escribió 'IFS =' pero el original es 'IFS =,' ¿hizo un error o la coma está ahí? para separar 'IFS' del otro contenido de la línea? –

+0

@eugene y: ¿Estás seguro? Lo he intentado en este momento, copiar pegado de commandlinefu.com y funciona ... –

+0

@Alberto: 'touch abc bcd cde; rmbut bcd # elimina "cde" only' –

Cuestiones relacionadas