Eu preciso entender esta linha de comando:
file=`echo $1 | xargs -n 1 basename | cut -d '.' -f1`
Responder1
Ele atribui um pouco de nome de arquivo (possivelmente com um caminho) à variável file
. Especificamente, o bit antes do primeiro .
caractere no nome do próprio arquivo. Em outras palavras, é preciso algo parecido /some/path/hello.world
e analisa a hello
parte.
Uma dica seria executar cada parte do pipeline na linha 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
Os crases são usados para retornar a saída do pipeline e atribuí-la a file
. Este $1
é o primeiro argumento na linha de comando (para qualquer script ou função shell da qual faz parte).
É provável que a única razão pela qual xargs -n 1 basename
seja usado em vez de simples basename
seja porque o basename
utilitário não lê a entrada padrão, mas xargs
o faz.
Uma versão mais curta (e mais rápida) da mesma coisa seria bash
ou ksh93
seria
file=${1##*/}
file=${file%%.*}
Responder2
A linha extrai os nomes dos arquivos sem extensões dos caminhos fornecidos via $1
(o primeiro argumento do script em que essa linha aparece). O resultado é salvo na variável file
.
Demonstração:
$ echo /etc/dhcpcd.conf ../foo/bar/filename.tar.gz | xargs -n 1 basename | cut -d '.' -f1
dhcpcd
filename
Responder3
A combinação de echo
e xargs
é bastante curiosa aqui.
basename
pega um nome de caminho na linha de comando e gera o componente final dele (ou seja, parte após a última barra, geralmente). xargs
apenas coloca as palavras lidas de sua entrada (o pipe) na linha de comando daqui basename
. Então por que não apenas usar basename $1
?
Há, no entanto, uma diferença.
Se echo $1 | xargs -n 1 basename
o parâmetro $1
contiver espaços em branco, xargs
irá dividi-lo em espaços e chamar basename
cada palavra separadamente. O resultado final será que uma parte do nome do arquivo será escolhida paratodosas palavras, comoArmínio mostrou.
A outra opção, basename $1
, chamaria basename
apenas uma vez (e falharia de algumas maneiras interessantes devido à divisão de palavras).
Se o comando deveria lidar apenas com um nome de arquivo, seria melhor escrito como:
file=$(basename "$1" | cut -d '.' -f 1)
Com as citações. (ou usando a expansão do shell de remoção de sufixos ${file%%.*}
em vez do cut
asKusalananda mostrou.)
Se, por outro lado, for necessário lidar com vários nomes de arquivos, pode ser mais limpo passá-los usando um array ou nos parâmetros posicionais (todos eles, não apenas $1
).
Responder4
A linha armazena o nome de um arquivo, sem extensão e caminho, na variável $file
.
Em detalhe:
echo $1
imprime o primeiro argumento da linha de comando passado para o script, xargs -n 1 basename
passa a string ecoada como argumentos para o comando basename
, que retira o caminho do nome do arquivo.
cut -d '.' -f1
remove a extensão.
Então, por exemplo, se você executar
echo directory/test.sh | xargs -n 1 basename | cut -d '.' -f1
o resultado (salvo em $file
) será test
.