Gostaria de excluir o último caractere de uma string, tentei este pequeno script:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
mas imprime "lkj", o que estou fazendo de errado?
fonte
Gostaria de excluir o último caractere de uma string, tentei este pequeno script:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
mas imprime "lkj", o que estou fazendo de errado?
Em um shell POSIX, a sintaxe ${t:-2}
significa algo diferente - ela se expande para o valor de t
se t
for definido e não nulo e, caso contrário, para o valor 2
. Para aparar um único caractere por expansão de parâmetro, a sintaxe que você provavelmente deseja é${t%?}
Observe que em ksh93
, bash
ou zsh
, ${t:(-2)}
ou ${t: -2}
(observe o espaço) são legais como uma expansão de substring, mas provavelmente não é o que você deseja, pois eles retornam o substring começando com uma posição de 2 caracteres a partir do final (ou seja, ele remove o primeiro caractere i
do string ijk
).
Consulte a seção Expansão de parâmetros do shell do Manual de referência do Bash para obter mais informações:
${parameter%word}
remove a menor correspondência de padrão de sufixoword
- consulte a seção Expansão de parâmetro deman bash
Com
bash
4.2 e acima, você pode fazer:Exemplo:
Observe que para os mais antigos
bash
(por exemplo,bash 3.2.5
no OS X), você deve deixar espaços entre dois pontos e depois:fonte
bash
versão 4.2-alpha e acima, muito ruim a versão à qual tenho acesso é anterior. : - /${var:offset:lenght}
foi adicionado apenas embash 4.2
. Talvez o OSX adicione seu próprio patch parabash
.para remover os últimos
n
caracteres de uma linha que não utilizased
ORawk
:portanto, por exemplo, você pode excluir o último caractere
one character
usando este:da
rev
página de manual:ATUALIZAR:
se você não souber o comprimento da string, tente:
fonte
Usando sed, deve ser tão rápido quanto
Seu único eco é então
echo ljk | sed 's/.$//'
.Usando isso, a cadeia de caracteres de 1 linha pode ter qualquer tamanho.
fonte
Algumas opções, dependendo do shell:
t=${t%?}
t=`expr " $t" : ' \(.*\).'`
t=${t[1,-2]}
t=${t:0:-1}
t=${t:0:${#t}-1}
t=${t/%?}
t=${t/~(E).$/}
@ {t=$1} ~~ $t *?
Observe que, embora todos devam remover o último caractere , você descobrirá que algumas implementações (aquelas que não suportam caracteres de vários bytes) retiram o último byte (portanto, isso provavelmente corromperá o último caractere se for multi-byte )
A
expr
variante assume$t
que não termina em mais de um caractere de nova linha. Ele também retornará um status de saída diferente de zero se a sequência resultante acabar sendo0
(000
ou mesmo-0
com algumas implementações). Também pode fornecer resultados inesperados se a sequência contiver caracteres inválidos.fonte
t=${t%?}
não é Bourne, mas você provavelmente não encontrará um shell Bourne hoje em dia.${t%?}
funciona em todos os outros embora.fish
é um trabalho em andamento. 2.3.0 que introduziu ostring
built-in não foi lançado no momento das perguntas e respostas. Com a versão em que estou testando, você precisastring replace -r '(?s).\z' '' -- $t
(e eu espero que eles mudem isso, eles devem mudar as bandeiras que passam para o PCRE) ou mais complicadas. Também lida mal com caracteres de nova linha, e eu sei que eles estão planejando mudar isso também.A resposta mais portátil e mais curta é quase certamente:
${t%?}
Isso funciona em bash, sh, ash, dash, busybox / ash, zsh, ksh, etc.
Ele funciona usando a expansão de parâmetros do shell da velha escola. Especificamente,
%
especifica para remover o menor sufixo de parâmetrot
correspondente ao padrão glob?
(ou seja: qualquer caractere).Consulte "Remover o menor padrão de sufixo" aqui para obter uma explicação (muito) mais detalhada e mais informações. Veja também os documentos do seu shell (por exemplo
man bash
:) em "expansão de parâmetros".Como observação, se você deseja remover o primeiro caractere, use-o
${t#?}
, pois#
corresponde da frente da string (prefixo) em vez da parte traseira (sufixo).Também digno de nota é que ambos
%
e#
have%%
e##
versões, que correspondem à versão mais longa do padrão fornecido, em vez da mais curta. Ambos${t%%?}
e${t##?}
fariam o mesmo que seu único operador nesse caso, no entanto (portanto, não adicione o caractere inútil). Isso ocorre porque o?
padrão fornecido corresponde apenas a um único caractere. Misture um*
com alguns caracteres não curinga e as coisas ficam mais interessantes com%%
e##
.Compreender as expansões de parâmetros, ou pelo menos saber sobre sua existência e saber procurá-las, é incrivelmente útil para escrever e decifrar scripts de shell de vários tipos. As expansões de parâmetro costumam parecer vodu arcano para muitas pessoas porque ... bem ... são vodu arcano (embora muito bem documentado se você souber procurar "expansão de parâmetro"). Definitivamente, é bom ter o cinto de ferramentas quando você está preso em uma concha.
fonte
Você obtém uma substring de 0 ao comprimento da string -1. Observe, no entanto, que essa subtração é específica do bash e não funciona em outros shells.
Por exemplo,
dash
não é capaz de analisar nemPor exemplo, no Ubuntu,
/bin/sh
édash
fonte
Você também pode
head
imprimir todos os caracteres, exceto o último.Infelizmente, porém, algumas versões
head
do não incluem a-
opção principal . Este é o caso dohead
que acompanha o OS X.fonte
É fácil o suficiente usando expressões regulares:
fonte
Alguns refinamentos. Para remover mais de um caractere, você pode adicionar vários pontos de interrogação. Por exemplo, para remover os dois últimos caracteres da variável:,
$SRC_IP_MSG
você pode usar:fonte
Apenas para concluir alguns usos possíveis do bash puro:
A primeira sintaxe pega uma substring de uma string, a sintaxe é. Para a segunda, observe o sinal, que significa 'do final da linha' e a sintaxe é
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
E aqui estão duas formas mais curtas do mencionado acima
Observe novamente o
%
sinal, que significa 'Remover (ou seja, substitua por' ') o padrão de correspondência mais curto (aqui representado pelo espaço escapado ' \ ' do final do PARÂMETRO - aqui chamado STRfonte
Como também podemos usar o php na linha de comando ou scripts de shell. Às vezes, é útil para análise cirúrgica.
Com tubulação:
fonte
Em ksh:
fonte