Bash remove o primeiro e o último caracteres de uma string

99

Eu tenho uma string assim:

|abcdefg|

E eu quero obter uma nova string chamada de alguma forma (como string2) com a string original sem os dois |caracteres no início e no final dela, para que eu tenha o seguinte:

abcdefg

Isso é possível no bash?

Matteo Pagliazzi
fonte

Respostas:

121

Você pode fazer

string="|abcdefg|"
string2=${string#"|"}
string2=${string2%"|"}
echo $string2

Ou se o comprimento da sua string for constante, você poderá

string="|abcdefg|"
string2=${string:1:7}
echo $string2

Além disso, isso deve funcionar

echo "|abcdefg|" | cut -d "|" -f 2

Também isso

echo "|abcdefg|" | sed 's/^|\(.*\)|$/\1/'
Kris Harper
fonte
2
e tambémawk -F\| '{ print $2 }' <<<"|string|"
enzotib 23/12/11
1
@enzotib Você sempre tem awksoluções legais . Eu preciso aprender awk.
Kris Harper
3
e também IFS='|' read string2 <<< $string:)
organize
10
e também, em bash 4,2 e mais recente,"${string:1:-1}"
geirha
Leia na seção "expansão de parâmetros" em man bash.
Nemo
62

Aqui está uma solução que é independente do comprimento da string (bash):

string="|abcdefg|"
echo "${string:1:${#string}-2}"
Samus_
fonte
29

Ao sair de alguns posts listados aqui, parece que a maneira mais simples de fazer isso é:

string="|abcdefg|"
echo ${string:1:-1}

edit: funciona no ubuntu com o bash 4.2; não funciona no centOS com bash 4.1

jlunavtgrad
fonte
20

Outra maneira é usar head& tailcomandos:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg
Zavior
fonte
1
Eu tinha uma série de coisas [something something]com o objetivo de cortar parênteses, então echo "[something something]" | tail -c +2 | head -c -2trabalhei. Obrigado por uma dica!
Ain Tohvri
Obviamente, deveria ser echo -n "|abcdefg|" | tail -c +2 | head -c -1. Não sei por que minhas edições foram rejeitadas ... É muito triste, para ser honesto. Veja man headpara mais informações
Dmitry Khamitov 27/03
10

E um outro:

string="|abcdefg|"
echo "${string//|/}"
Steven Penny
fonte
9

Você também pode usar o sed para remover o | não apenas referenciando o próprio símbolo, mas usando referências posicionais como em:

$ echo "|abcdefg|" | sed 's:^.\(.*\).$:\1:'
abcdefg

Onde ':' são os delimitadores (você pode substituí-los por / ou qualquer caractere que não esteja na consulta, qualquer sinal após s fará isso) Aqui ^ (acento circunflexo) significa no início da string de entrada e $ (dólar) significa no fim. O . (ponto) que está após o sinal de intercalação e o que está antes do cifrão representa um único caractere. Portanto, em outras palavras, estamos excluindo o primeiro e o último caracteres. Lembre-se de que isso excluirá qualquer caractere, mesmo que | não está presente na string.

EX:

$ echo "abcdefg" | sed 's:^.\(.*\).$:\1:'
bcdef
Metafaniel
fonte
3

função shell

Uma abordagem um pouco mais detalhada, mas funciona com qualquer tipo de primeiro e último caractere, não precisa ser a mesma. A idéia básica é que estamos pegando uma variável, lendo-a caractere por caractere e acrescentando apenas aqueles que queremos a uma nova variável

Aqui está toda essa ideia formatada em uma boa função

crop_string_ends() {
    STR="$1" 
    NEWSTR="" 
    COUNT=0 
    while read -n 1 CHAR 
    do
        COUNT=$(($COUNT+1)) 
        if [ $COUNT -eq 1 ] || [ $COUNT -eq ${#STR} ] 
        then
            continue 
        fi 
        NEWSTR="$NEWSTR"$CHAR 
    done <<<"$STR" 
    echo $NEWSTR 
}

E aqui está a mesma função em ação:

$> crop_string_ends "|abcdefg|"                                                                                       
abcdefg
$> crop_string_ends "HelloWorld"                                                                                      
elloWorl

Pitão

>>> mystring="|abcdefg|"
>>> print(mystring[1:-1])
abcdefg

ou na linha de comando:

$ python -c 'import sys;print sys.stdin.read()[1:-2]' <<< "|abcdefg|"                                             
abcdefg

AWK

$ echo "|abcdefg|" | awk '{print substr($0,2,length($0)-2)}'                                                      
abcdefg

Rubi

$ ruby -ne 'print $_.split("|")[1]' <<< "|abcdefg|"                                                               
abcdefg
Sergiy Kolodyazhnyy
fonte
2

Solução pequena e universal:

expr "|abcdef|" : '.\(.*\).'

Especial neste caso e permitindo que o '|' personagem pode estar lá ou não:

expr "|abcdef" : '|*\([^|]*\)|*'
Tosi Do
fonte
2
$ string="|abcdefg|"
$ string="${string#?}" && string="${string%%?}"
$ echo "$string"
abcdefg

De http://tldp.org/LDP/abs/html/parameter-substitution.html

${var#Pattern}
Retire do $vara menor parte $Patternque coincide com o fim dianteiro de $var. Retire do a maior parte do que coincide com o back-end de .
${var%%Pattern}
$var$Pattern$var

Brian
fonte