var=123456
echo "${var#"${var%???}"}"
###OUTPUT###
456
Isso remove primeiro os três últimos caracteres de $var
e, em seguida, remove de $var
os resultados dessa remoção - o que retorna os três últimos caracteres de $var
. Aqui estão alguns exemplos mais especificamente destinados a demonstrar como você pode fazer uma coisa dessas:
touch file.txt
path=${PWD}/file.txt
echo "$path"
/tmp/file.txt
base=${path##*/}
exten=${base#"${base%???}"}
base=${base%."$exten"}
{
echo "$base"
echo "$exten"
echo "${base}.${exten}"
echo "$path"
}
file
txt
file.txt
/tmp/file.txt
Você não precisa espalhar tudo isso por meio de tantos comandos. Você pode compactar isso:
{
base=${path##*/} exten=
printf %s\n "${base%.*}" "${exten:=${base#"${base%???}"}}" "$base" "$path"
echo "$exten"
}
file
txt
file.txt
/tmp/file.txt
txt
A combinação dos parâmetros $IFS
with set
ting shell também pode ser um meio muito eficaz de analisar e analisar as variáveis do shell:
(IFS=. ; set -f; set -- ${path##*/}; printf %s "${1#"${1%???}"}")
Isso fornecerá apenas os três caracteres imediatamente anteriores ao primeiro período após o último /
em $path
. Se você deseja recuperar apenas os três primeiros caracteres imediatamente anteriores ao último .
em $path
(por exemplo, se houver uma possibilidade de mais de um .
no nome do arquivo) :
(IFS=.; set -f; set -- ${path##*/}; ${3+shift $(($#-2))}; printf %s "${1#"${1%???}"}")
Em ambos os casos, você pode fazer:
newvar=$(IFS...)
E ...
(IFS...;printf %s "$2")
... imprimirá o que segue o .
Se você não se importa em usar um programa externo, faça o seguinte:
printf %s "${path##*/}" | sed 's/.*\(...\)\..*//'
Se houver uma chance de um caractere de \n
ewline no nome de arquivo (não aplicável para as soluções de shell nativas - todas elas lidam com isso de qualquer maneira) :
printf %s "${path##*/}" | sed 'H;$!d;g;s/.*\(...\)\..*//'