Explique este script bash: echo “$ {1 ## *.}” [duplicado]

17

Considere o seguinte script bash:

#!/bin/bash
echo "${1##*.}" 

Este script imprime a extensão de um arquivo se o nome do arquivo for fornecido como o primeiro argumento de linha de comando, algo como:

$ ./script.sh ./file.pdf

No caso acima, pdf é impresso.

Por favor, explique como a expressão ${1##*.} é capaz de extrair a extensão do arquivo.

(Eu entendo o que $ 0, $ 1, $ 2, $ # fazem no bash e também entendo sobre expressões regulares até certo ponto)

    
por DUKE 31.07.2014 / 04:57

3 respostas

27

A expansão de parâmetro Bash suporta várias modificações que pode fazer no valor enquanto expande uma variável. Um deles é ## , que remove o prefixo mais longo de o valor que corresponde a um padrão (os padrões não são expressões regulares aqui).

Nesse caso, o padrão é *. . Isso corresponde a zero ou mais caracteres seguidos por . . ${x##*.} significa remover toda a cadeia até o último caractere . e deixar tudo depois desse ponto.

${1##*.} significa fazer essa expansão usando o valor do primeiro parâmetro posicional, o que você normalmente acessaria com $1 . O resultado final de

echo "${1##*.}"

é então imprimir a parte do primeiro argumento do script que vem depois do último . , que é a extensão do nome do arquivo.

Se o padrão não corresponder , o valor total da variável será expandido, como se você não tivesse usado o ## . Nesse caso, se o argumento que você deu não tiver um . , você poderá simplesmente retirá-lo novamente.

O Bash também suporta um único # para desativar o menor prefixo correspondente e a mesma coisa com % para corresponder ao final da string.

    
por 31.07.2014 / 05:03
6

Exemplo simples:

$ A=my.file.name.txt

$ echo ${A}
my.file.name.txt

$ echo ${A#m}
y.file.name.txt

$ echo ${A#my}
.file.name.txt

$ echo ${A#*.}
file.name.txt

$ echo ${A##*.}
txt

Em um script, $ {1} é o primeiro argumento, e o mesmo conceito se aplica.

    
por 31.07.2014 / 19:01
4

Nota: expansão do parâmetro Bash:

Você pode aparar uma string da cabeça usando # operator

Você pode cortar uma string da cauda usando% operator

vamos dar um exemplo:

[my->prompt]$ VAR="head:string:tail"
[my->prompt]$ echo ${VAR##*:}               //trim from the head -> till the last ':'
tail
[my->prompt]$ echo ${VAR#*:}                //trim from the head -> till the first ':' 
string:tail
[my->prompt]$ echo ${VAR%%:*}               //trim from the tail <- till the last ':'
head
[my->prompt]$ echo ${VAR%:*}                //trim from the tail <- till the first ':'
head:string
[my->prompt]$ VAR2=${VAR%:*}                //VAR2="head:string"
[my->prompt]$ echo $VAR2
head:string
[my->prompt]$ echo ${VAR2#*:}               //trim from the head -> till the first ':' 
string
    
por 31.07.2014 / 19:26

Tags