Como 'soltar' / apagar caracteres na frente de uma string?

8

Eu tenho uma string que gostaria de manipular. A string é H08W2345678 , como eu poderia manipulá-la para que a saída seja apenas W2345678 ?

Da mesma forma, se eu quisesse eliminar os últimos 4 caracteres de H08W2345678 para que eu obtivesse H08W234 , como eu faria isso?

    
por 3kstc 08.04.2015 / 01:12

4 respostas

11

Apenas usando bash (ou ksh93 de onde vem essa sintaxe ou zsh ):

string="H08W2345678"

echo "${string:3}"
W2345678

echo "${string:0:-4}"
H08W234

Veja o wiki do Wooledge para saber mais sobre manipulação de string .

    
por 08.04.2015 / 01:19
5
$ echo "H08W2345678" | sed 's/^.\{3\}//'
W2345678

sed 's/^.\{3\}//' encontrará os três primeiros caracteres em ^.\{3\} e substituirá por branco. Aqui ^. corresponderá a qualquer caractere no início da string ( ^ indica o início da string) e \{3\} corresponderá ao padrão anterior exatamente 3 vezes. Então, ^.\{3\} irá corresponder aos três primeiros caracteres.

$ echo "H08W2345678" | sed 's/.\{4\}$//'
H08W234

Da mesma forma, sed 's/.\{4\}$//' substituirá os quatro últimos caracteres em branco ( $ indica o final da string).

    
por 08.04.2015 / 01:15
2

Se você tem um arquivo no qual cada linha é uma cadeia de onze caracteres (ou qualquer outra) que você queira cortar, sed é a ferramenta a ser usada. É bom para manipular uma única string, mas é um exagero. Para uma única string, a resposta de Jason é provavelmente a melhor, se você tiver acesso ao bash versão 4.2 ou superior. No entanto, o ${parameter:offset} e ${parameter:offset:length} sintaxes parece ser exclusivo para bash (bem, bash, ksh93, mksh e zsh) - Eu não os vejo em As especificações básicas do grupo aberto para a linguagem de comando do Shell . Se você está preso a um shell compatível com POSIX que não suporta expansão de substring (extração), você pode usar

$ printf "%s\n" "${string#???}"
W2345678

$ printf "%s\n" "${string%????}"
H08W234

usando printf em vez de echo para proteger contra strings como abc-e , onde, quando você soltar os três primeiros caracteres, você fica com -e (e echo -e não faz o que você deseja).

E, se você não estiver usando um shell da família Bourne (ou você está usando um antigo sistema pré-POSIX), eles ainda devem funcionar:

$ expr " $string" : ' ...\(.*\)'
W2345678

$ expr " $string" : ' \(.*\)....'
H08W234

O espaço extra extra é para evitar problemas com valores de $string que são operadores expr reais (por exemplo, + , / , index ou match ) ou opções (por exemplo, -- , --help ou --version ).

    
por 08.04.2015 / 02:18
0

Com:

string="H08W2345678"

Correspondência de 3 ou 4 caracteres parece simples (para a maioria das shells):

$ printf '%s\t%s\n' "${string#???}" "${string%????}"
W2345678      H08W234

Para os shells mais antigos (como o shell Bourne), use:

$ string=H08W2345678

$ expr " ${string}" : " ...\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\)...." '
H08W234

Se for necessária uma contagem numérica de caracteres, use:

$ expr " ${string}" : " .\{3\}\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\).\{4\}" '
H08W234

Claro, esses regex funcionam também com sed, awk e bash 3.0 +:

$ echo "$string" | sed 's/^.\{3\}//'
W2345678

$ echo "$string" | sed 's/.\{4\}$//'
H08W234

$ echo "$string" | awk '{sub(/^.{3}/,"")}1'
W2345678

$ echo "$string" | awk '{sub(/.{4}$/,"")}1'
H08W234

$ r='^.{3}(.*)$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
W2345678

$ r='^(.*).{4}$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
H08W234
    
por 09.06.2018 / 05:41