Bash eliminar el primer y último carácter de una cadena

81

Tengo una cadena como esa:

|abcdefg|

Y quiero obtener una nueva cadena llamada de alguna manera (como string2) con la cadena original sin las dos | al principio y al final de él

para que tenga esto

abcdefg

¿Es eso posible en bash?

    
pregunta Matteo Pagliazzi 23.12.2011 - 15:29

8 respuestas

107

Puedes hacerlo

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

O si la longitud de tu cadena es constante, puedes hacerlo

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

Además, esto debería funcionar

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

También esto

echo "|abcdefg|" | sed 's/^|\(.*\)|$//'
    
respondido por el Kris Harper 23.12.2011 - 15:49
56

Aquí hay una solución que es independiente de la longitud de la cadena (bash):

string="|abcdefg|"
echo "${string:1:${#string}-2}"
    
respondido por el Samus_ 24.12.2011 - 17:28
21

Saliendo de algunas publicaciones que se enumeran aquí, parece que la forma más sencilla de hacerlo es:

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

editar: funciona en ubuntu con bash 4.2; no funciona en centOS con bash 4.1

    
respondido por el jlunavtgrad 05.09.2012 - 22:37
10

Y otro:

string="|abcdefg|"
echo "${string//|/}"
    
respondido por el Steven Penny 09.06.2012 - 03:03
10

Otra forma con la cabeza y amp; cola:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -1
abcdefg
    
respondido por el Zavior 26.11.2013 - 17:16
8

También puedes usar sed para eliminar el | no solo hace referencia al símbolo en sí, sino que utiliza referencias posicionales como en:

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

Donde ':' son los delimitadores (puede reemplazarlos con / o cualquier carácter que no esté en la consulta, cualquier signo que siga a la s lo hará) Aquí ^ (caret) significa al principio de la cadena de entrada y $ ( dólar) significa al final. Los . (punto) que se encuentra después del cursor y el que está antes del signo de dólar representa un solo carácter. En otras palabras, estamos eliminando el primer y último carácter. Tenga en cuenta que esto eliminará cualquier carácter incluso si | no está presente en la cadena.

EX:

$ echo "abcdefg" | sed 's:^.\(.*\).$::'
bcdef
    
respondido por el Metafaniel 08.02.2012 - 02:44
2

función de shell

Un enfoque un poco más detallado, pero funciona en cualquier tipo de primer y último carácter, no tiene que ser el mismo. La idea básica es que estamos tomando una variable, leyéndola carácter por carácter, y agregando solo aquellos Queremos una nueva variable

Aquí está toda la idea formateada en una buena función

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 
}

Y aquí está la misma función en acción:

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

Python

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

o en la línea 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

Ruby

$ ruby -ne 'print $_.split("|")[1]' <<< "|abcdefg|"                                                               
abcdefg
    
respondido por el Sergiy Kolodyazhnyy 06.04.2016 - 15:58
1

Solución pequeña y universal:

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

Especial en este caso y permitiendo que el '|' El personaje puede estar allí o no:

expr "|abcdef" : '|*\([^|]*\)|*'
    
respondido por el Tosi Do 09.07.2017 - 01:29

Lea otras preguntas en las etiquetas