Respostas:
Últimos três caracteres de string
:
${string: -3}
ou
${string:(-3)}
(observe o espaço entre :
e -3
na primeira forma).
Consulte a Expansão dos parâmetros do shell no manual de referência :
${parameter:offset}
${parameter:offset:length}
Expands to up to length characters of parameter starting at the character
specified by offset. If length is omitted, expands to the substring of parameter
starting at the character specified by offset. length and offset are arithmetic
expressions (see Shell Arithmetic). This is referred to as Substring Expansion.
If offset evaluates to a number less than zero, the value is used as an offset
from the end of the value of parameter. If length evaluates to a number less than
zero, and parameter is not ‘@’ and not an indexed or associative array, it is
interpreted as an offset from the end of the value of parameter rather than a
number of characters, and the expansion is the characters between the two
offsets. If parameter is ‘@’, the result is length positional parameters
beginning at offset. If parameter is an indexed array name subscripted by ‘@’ or
‘*’, the result is the length members of the array beginning with
${parameter[offset]}. A negative offset is taken relative to one greater than the
maximum index of the specified array. Substring expansion applied to an
associative array produces undefined results.
Note that a negative offset must be separated from the colon by at least one
space to avoid being confused with the ‘:-’ expansion. Substring indexing is
zero-based unless the positional parameters are used, in which case the indexing
starts at 1 by default. If offset is 0, and the positional parameters are used,
$@ is prefixed to the list.
Como esta resposta obtém algumas visões regulares, deixe-me acrescentar a possibilidade de abordar o comentário de John Rix ; como ele menciona, se a sua string tiver comprimento menor que 3, ela se ${string: -3}
expandirá para a string vazia. Se, nesse caso, você desejar a expansão de string
, poderá usar:
${string:${#string}<3?0:-3}
Isso usa o ?:
operador ternário se, que pode ser usado na aritmética do shell ; como documentado, o deslocamento é uma expressão aritmética, isso é válido.
deppfx@localhost:/tmp$ echo ${$(hostname): -3}
-bash: ${$(hostname): -3}: bad substitution
temp=$(hostname); echo "${temp: -3}"
. O Bash também possui a HOSTNAME
variável (que pode ou não diferir da saída de hostname
). Se você quiser usá-lo, apenas faça echo "${HOSTNAME: -3}"
.
some func | echo ${string: -3}
- como atribuo a saída de some func
para string
?
string=$(some func)
e então echo "${string: -3}"
.
Você pode usar tail
:
$ foo="1234567890"
$ echo -n $foo | tail -c 3
890
Uma maneira um tanto indireta de obter os três últimos caracteres seria dizer:
echo $foo | rev | cut -c1-3 | rev
Outra solução alternativa é usar grep -o
com um pouco de magia regex para obter três caracteres seguidos até o final da linha:
$ foo=1234567890
$ echo $foo | grep -o ...$
890
Para obter opcionalmente os 1 a 3 últimos caracteres, no caso de cadeias com menos de 3 caracteres, você pode usar egrep
com esta regex:
$ echo a | egrep -o '.{1,3}$'
a
$ echo ab | egrep -o '.{1,3}$'
ab
$ echo abc | egrep -o '.{1,3}$'
abc
$ echo abcd | egrep -o '.{1,3}$'
bcd
Você também pode usar intervalos diferentes, como 5,10
os últimos cinco a dez caracteres.
Para generalizar a pergunta e a resposta de gniourf_gniourf (como era isso que eu estava procurando), se você deseja cortar um intervalo de caracteres de, digamos, 7 do final para 3 do final, você pode usar esta sintaxe:
${string: -7:4}
Onde 4 é a duração do curso (7-3).
Além disso, embora a solução de gniourf_gniourf seja obviamente a melhor e mais organizada, eu só queria adicionar uma solução alternativa usando o cut :
echo $string | cut -c $((${#string}-2))-$((${#string}))
Isso é mais legível se você fizer isso em duas linhas, definindo o comprimento $ {# string} como uma variável separada.
cut
abordagem de calcular o início / parada primeiro e, em seguida, apenas usar essas variáveis na expansão de parâmetros (também vale mencionar que os cut
desvios bash e iniciam em 1 e zero, respectivamente, portanto, seria necessário para ser calculado nos cálculos, o que não estou fazendo aqui): start=$((${#string}-3)); stop=$((${#string}));
e depois echo ${string: $start : $stop}
vsecho $string | cut -c "$start"-"$stop"