Necesito entender esta línea de comando:
file=`echo $1 | xargs -n 1 basename | cut -d '.' -f1`
Respuesta1
Asigna un poco de nombre de archivo (posiblemente con una ruta) a la variable file
. Específicamente, el bit antes del primer .
carácter en el nombre del archivo. En otras palabras, toma algo así como /some/path/hello.world
y analiza el hello
bit.
Un consejo sería ejecutar cada parte del proceso en la línea de comando:
$ thing="/some/path/hello.world"
$ echo "$thing"
/some/path/hello.world
$ echo "$thing" | xargs -n 1 basename
hello.world
$ echo "$thing" | xargs -n 1 basename | cut -d '.' -f 1
hello
Las comillas invertidas se utilizan para devolver la salida de la canalización y asignarla a file
. Es $1
el primer argumento en la línea de comando (para cualquier script o función de shell del que forme parte).
Es probable que la única razón por la que xargs -n 1 basename
se utiliza en lugar de simple basename
sea que la basename
utilidad no lee la entrada estándar, pero xargs
lo hace.
Una versión más corta (y más rápida) de lo mismo en bash
o ksh93
sería
file=${1##*/}
file=${file%%.*}
Respuesta2
La línea extrae los nombres de archivos sin extensiones de las rutas proporcionadas mediante $1
(el primer argumento del script en el que aparece esa línea). El resultado se guarda en la variable file
.
Manifestación:
$ echo /etc/dhcpcd.conf ../foo/bar/filename.tar.gz | xargs -n 1 basename | cut -d '.' -f1
dhcpcd
filename
Respuesta3
La combinación de echo
y xargs
es bastante curiosa aquí.
basename
toma un nombre de ruta en la línea de comando y genera el componente final (es decir, la parte después de la última barra, generalmente). xargs
simplemente coloca las palabras leídas desde su entrada (la tubería) en la línea de comando de basename
aquí. Entonces, ¿por qué no utilizar simplemente basename $1
?
Sin embargo, hay una diferencia.
Si echo $1 | xargs -n 1 basename
el parámetro $1
contiene espacios en blanco, xargs
lo dividirá en espacios y llamará basename
a cada palabra por separado. El resultado final será que una parte del nombre del archivo será seleccionada paratodolas palabras, comoArminio mostró.
La otra opción, basename $1
, llamaría basename
solo una vez (y fallaría de alguna manera debido a la división de palabras).
Si se supone que el comando solo maneja un nombre de archivo, sería mejor escribirlo como:
file=$(basename "$1" | cut -d '.' -f 1)
Con las comillas. (o usando la expansión de shell de eliminación de sufijos ${file%%.*}
en lugar de cut
asKusalananda mostró.)
Si, por otro lado, se supone que debe manejar varios nombres de archivos, podría ser más limpio pasarlos usando una matriz o en los parámetros posicionales (todos, no solo $1
).
Respuesta4
La línea almacena el nombre de un archivo, sin extensión ni ruta, en la variable $file
.
En detalle:
echo $1
imprime el primer argumento de la línea de comando pasado al script, xargs -n 1 basename
pasa la cadena repetida como argumentos al comando basename
, lo que elimina la ruta del nombre del archivo.
cut -d '.' -f1
elimina la extensión.
Entonces, por ejemplo si ejecutas
echo directory/test.sh | xargs -n 1 basename | cut -d '.' -f1
el resultado (guardado en $file
) será test
.