¿Qué hace esta línea de comando (`echo $1 | xargs -n 1 basename | cut -d '.' -f1`)?

¿Qué hace esta línea de comando (`echo $1 | xargs -n 1 basename | cut -d '.' -f1`)?

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.worldy analiza el hellobit.

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 $1el 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 basenamese utiliza en lugar de simple basenamesea que la basenameutilidad no lee la entrada estándar, pero xargslo hace.

Una versión más corta (y más rápida) de lo mismo en basho ksh93serí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 echoy xargses bastante curiosa aquí.

basenametoma 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). xargssimplemente coloca las palabras leídas desde su entrada (la tubería) en la línea de comando de basenameaquí. Entonces, ¿por qué no utilizar simplemente basename $1?

Sin embargo, hay una diferencia.

Si echo $1 | xargs -n 1 basenameel parámetro $1contiene espacios en blanco, xargslo dividirá en espacios y llamará basenamea 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 basenamesolo 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 cutasKusalananda 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 $1imprime el primer argumento de la línea de comando pasado al script, xargs -n 1 basenamepasa la cadena repetida como argumentos al comando basename, lo que elimina la ruta del nombre del archivo. cut -d '.' -f1elimina 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.

información relacionada