O que esta linha de comando ('echo $ 1 | xargs -n 1 basename | cut -d'. '-f1') faz? [fechadas]

1

Eu preciso entender esta linha de comando:

file='echo $1 | xargs -n 1 basename | cut -d '.' -f1'
    
por Matias 13.04.2017 / 20:01

4 respostas

2

Atribui um pouco de um nome de arquivo (possivelmente com um caminho) à variável file . Especificamente, o bit antes do primeiro caractere . no nome do arquivo do próprio arquivo. Em outras palavras, é preciso algo como /some/path/hello.world e analisa o hello bit.

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 backticks são usados para retornar a saída do pipeline e atribuí-la a file . O $1 é o primeiro argumento na linha de comando (para qualquer script ou função de shell da qual faça parte).

É provável que a única razão xargs -n 1 basename seja usada em vez de basename simples é que o utilitário basename não lê da entrada padrão, mas xargs faz.

Uma versão mais curta (e mais rápida) da mesma coisa em bash ou ksh93 seria

file=${1##*/}
file=${file%%.*}
    
por 13.04.2017 / 20:14
1

A linha extrai os nomes dos arquivos sem extensões dos caminhos fornecidos via $1 (o primeiro argumento para o script em que essa linha aparece). O resultado é salvo na variável file .

Demo:

$ echo /etc/dhcpcd.conf ../foo/bar/filename.tar.gz | xargs -n 1 basename | cut -d '.' -f1
dhcpcd
filename
    
por 13.04.2017 / 20:10
1

A combinação de echo e xargs é bastante curiosa aqui.

basename assume 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 canal) na linha de comando de basename here. Então, por que não usar apenas basename $1 ?

Existe, no entanto, uma diferença.

Em echo $1 | xargs -n 1 basename se o parâmetro $1 contiver espaço em branco, xargs dividirá o espaço e chamará basename para cada palavra separadamente. O resultado final será que uma parte do nome do arquivo será escolhida para todas as palavras, como Arminius mostrou .

A outra opção, basename $1 , chamaria basename apenas uma vez (e falharia de alguma forma interessante devido à divisão de palavras.)

Se o comando deve manipular apenas um nome de arquivo, seria melhor escrito como:

file=$(basename "$1" | cut -d '.' -f 1)

Com as aspas. (ou usando a expansão do shell de exclusão de sufixo ${file%%.*} em vez do cut como Kusalananda mostrou .)

Se, por outro lado, ele deve manipular vários nomes de arquivos, pode ser mais fácil passá-los usando uma matriz ou nos parâmetros posicionais (todos eles, não apenas $1 ).

    
por 13.04.2017 / 21:28
0

A linha armazena o nome de um arquivo, sem extensão e caminho, na variável $file .

Em detalhes:

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 .

    
por 13.04.2017 / 20:24

Tags