Bash supprime les premier et dernier caractères d'une chaîne

100

J'ai une ficelle comme ça:

|abcdefg|

Et je veux obtenir une nouvelle chaîne appelée quelque part (comme chaîne2) avec la chaîne originale sans les deux |caractères au début et à la fin, de façon à avoir ceci:

abcdefg

Est-ce possible à Bash?

Matteo Pagliazzi
la source

Réponses:

121

Tu peux faire

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

Ou si votre longueur de chaîne est constante, vous pouvez faire

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

En outre, cela devrait fonctionner

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

Aussi cette

echo "|abcdefg|" | sed 's/^|\(.*\)|$/\1/'
Kris Harper
la source
2
et aussiawk -F\| '{ print $2 }' <<<"|string|"
enzotib
1
@enzotib Vous avez toujours des awksolutions sympas . J'ai besoin d'apprendre awk.
Kris Harper
3
et aussi IFS='|' read string2 <<< $string:)
arranger
10
et aussi, dans bash 4.2 et plus récent,"${string:1:-1}"
geirha
Lisez sous la section "expansion des paramètres" dans man bash.
Nemo
63

Voici une solution indépendante de la longueur de la chaîne (bash):

string="|abcdefg|"
echo "${string:1:${#string}-2}"
Samus_
la source
30

Après quelques articles listés ici, il semble que le moyen le plus simple de le faire est:

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

edit: fonctionne sur Ubuntu avec Bash 4.2; ne fonctionne pas sur centOS avec bash 4.1

jlunavtgrad
la source
21

Une autre façon est d'utiliser head& tailcommandes:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg
Zavior
la source
1
J'avais une ficelle de [something something]but avec l'objectif de couper les crochets, donc j'ai bien echo "[something something]" | tail -c +2 | head -c -2travaillé. Merci pour un tuyau!
Ain Tohvri
Évidemment, ça devrait l'être echo -n "|abcdefg|" | tail -c +2 | head -c -1. Je ne suis pas sûr de savoir pourquoi mes modifications ont été rejetées ... C'est très triste, pour être honnête. Voir man headpour plus d'informations
Dmitry Khamitov
10

Et un autre:

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

Vous pouvez également utiliser sed pour supprimer le | pas simplement en référençant le symbole lui-même mais en utilisant des références de position comme dans:

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

Où ':' sont les délimiteurs (vous pouvez les remplacer par tout caractère ne figurant pas dans la requête, tout signe suivant le s le fera) Ici ^ (caret) signifie au début de la chaîne d'entrée et $ (dollar) signifie à la fin. Le . (point) que c'est après le curseur et celui qui est avant le signe dollar représente un seul caractère. En d'autres termes, nous supprimons les premier et dernier caractères. Gardez à l'esprit que cela supprimera tous les caractères, même si | ce n'est pas présent dans la chaîne.

EX:

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

fonction shell

Une approche un peu plus verbeuse, mais qui fonctionne sur tous les types de premier et dernier caractères, ne doit pas nécessairement être identique. L'idée de base est que nous prenons une variable, la lisons caractère par caractère et ajoutons uniquement ceux que nous souhaitons à une nouvelle variable.

Voici toute cette idée formatée dans une fonction intéressante

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 
}

Et voici la même fonction en action:

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

Python

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

ou en ligne de commande:

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

AWK

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

Rubis

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

Solution petite et universelle:

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

Spécial dans ce cas et permettant que le '|' personnage peut être ou non:

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

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

${var#Pattern}
Supprimer de $varla partie la plus courte de $Patterncelle qui correspond à l' extrémité avant de $var. Supprimer de la partie la plus longue de celle qui correspond à la fin de .
${var%%Pattern}
$var$Pattern$var

Brian
la source