Je voudrais supprimer le dernier caractère d'une chaîne, j'ai essayé ce petit script:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
mais il affiche "lkj", qu'est-ce que je fais mal?
la source
Je voudrais supprimer le dernier caractère d'une chaîne, j'ai essayé ce petit script:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
mais il affiche "lkj", qu'est-ce que je fais mal?
Dans un shell POSIX, la syntaxe ${t:-2}
signifie quelque chose de différent - elle se développe à la valeur de t
if t
est définie et non nulle, et sinon à la valeur 2
. Pour ajuster un seul caractère par développement de paramètre, la syntaxe que vous souhaitez probablement est la suivante:${t%?}
Notez que ksh93
, bash
ou zsh
, ${t:(-2)}
ou ${t: -2}
(notez l'espace) sont légal comme l' expansion de sous - chaîne , mais probablement pas ce que vous voulez, car ils retournent la sous - chaîne commençant à une position 2 caractères à partir de la fin (il supprime le premier caractère i
du chaîne ijk
).
Reportez-vous à la section Extension des paramètres de shell du Manuel de référence de Bash pour plus d'informations:
${parameter%word}
supprime le suffixe le plus court correspondantword
- voir la section Expansion des paramètres deman bash
Avec
bash
4.2 et plus, vous pouvez faire:Exemple:
Notez que pour les anciens
bash
(par exemple,bash 3.2.5
sous OS X), vous devez laisser des espaces entre et après les deux points:la source
bash
version 4.2-alpha et supérieure, dommage que la version à laquelle j'ai accès soit antérieure. : - /${var:offset:lenght}
été ajoutée uniquement dansbash 4.2
. Peut-être que OSX ajoute son propre patch pourbash
.pour supprimer les derniers
n
caractères d'une ligne qui ne fait pas usage desed
OUawk
:Ainsi, par exemple, vous pouvez supprimer le dernier caractère en
one character
utilisant ceci:depuis la
rev
page de manuel:MISE À JOUR:
si vous ne connaissez pas la longueur de la chaîne, essayez:
la source
En utilisant sed, il devrait être aussi rapide que
Votre seul écho est alors
echo ljk | sed 's/.$//'
.En utilisant cela, la chaîne d'une ligne pourrait avoir n'importe quelle taille.
la source
Quelques options en fonction du 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 *?
Notez que bien que tous soient supposés effacer le dernier caractère , vous constaterez que certaines implémentations (celles qui ne prennent pas en charge les caractères multi-octets) suppriment le dernier octet à la place (ce qui risquerait donc de corrompre le dernier caractère s'il était multi-octets. ).
La
expr
variante suppose que$t
ne se termine pas par plus d'un caractère de nouvelle ligne. Il retournera également un statut de sortie non nul si la chaîne résultante finit par être0
(000
ou même-0
avec certaines implémentations). Cela pourrait également donner des résultats inattendus si la chaîne contient des caractères non valides.la source
t=${t%?}
n'est pas Bourne mais vous ne rencontrerez probablement pas un shell Bourne de nos jours.${t%?}
fonctionne dans tous les autres cependant.fish
est en cours. La version 2.3.0 qui a introduit la fonctionstring
intégrée n’a pas été publiée au moment de la période de questions. Avec la version que je teste, il vous fautstring replace -r '(?s).\z' '' -- $t
(et je m'attendrais à ce qu'ils veuillent changer ça, ils devraient changer les drapeaux qu'ils passent à PCRE) ou plus compliqués. Il traite également mal les caractères de nouvelle ligne, et je sais qu'ils envisagent de changer cela également.La réponse la plus portable et la plus courte est presque certainement:
${t%?}
Cela fonctionne en bash, sh, ash, dash, busybox / ash, zsh, ksh, etc.
Cela fonctionne en utilisant l'expansion des paramètres de shell old-school. Spécifiquement, le
%
spécifie de supprimer le plus petit suffixe correspondant du paramètret
qui correspond au motif global?
(c'est-à-dire: n'importe quel caractère).Voir "Supprimer le plus petit modèle de suffixe" ici pour une explication (beaucoup) plus détaillée et plus de fond. Consultez également la documentation de votre shell (par exemple:)
man bash
sous "Développement des paramètres".En guise de remarque, si vous souhaitez supprimer le premier caractère à la place, vous utiliserez
${t#?}
, puisque les#
correspondances se trouvent à l'avant de la chaîne (préfixe) au lieu de l'arrière (suffixe).Il faut également noter que les deux
%
et#
ont%%
et##
versions, qui correspondent à la plus longue version du motif donné au lieu de la plus courte. Les deux${t%%?}
et${t##?}
feraient la même chose que leur opérateur unique dans ce cas, cependant (alors n’ajoutez pas le caractère supplémentaire inutile). En effet, le?
modèle donné ne correspond qu’à un seul caractère. Ajoutez des*
éléments non génériques et les choses deviennent plus intéressantes avec%%
et##
.Comprendre les développements de paramètres, ou au moins connaître leur existence et savoir les rechercher, est extrêmement utile pour écrire et déchiffrer des scripts shell de nombreuses versions. Les extensions de paramètres ressemblent souvent à des arcanes dans un shell voodoo parce que ... bien ... ce sont des arcanes dans un vaudou (bien que très bien documentées si vous savez rechercher "une expansion des paramètres"). C'est vraiment bien d'avoir dans la ceinture à outils quand on est coincé dans une coquille, cependant.
la source
Vous obtenez une sous-chaîne de 0 à la longueur de chaîne -1. Notez cependant que cette soustraction est spécifique à bash et ne fonctionnera pas sur d'autres shells.
Par exemple,
dash
n'est pas capable d'analyser mêmePar exemple, sur Ubuntu,
/bin/sh
estdash
la source
Vous pouvez également utiliser
head
pour imprimer tout sauf le dernier caractère.Mais malheureusement, certaines versions de
head
n'incluent pas l'-
option principale . C'est le cas dehead
celui fourni avec OS X.la source
Il est assez facile de faire en utilisant une expression régulière:
la source
Quelques raffinements. Pour supprimer plusieurs caractères, vous pouvez ajouter plusieurs points d'interrogation. Par exemple, pour supprimer les deux derniers caractères de la variable:,
$SRC_IP_MSG
vous pouvez utiliser:la source
Juste pour compléter quelques utilisations possibles de pure bash:
La première syntaxe prend une sous-chaîne d'une chaîne, la syntaxe est la suivante: pour la seconde, remarquez le signe, ce qui signifie 'depuis la fin de la ligne' et la syntaxe est
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
Et voici deux formes plus courtes de ce qui précède
Ici encore, remarquez le
%
signe, signifiant 'Supprimer (c'est-à-dire, remplacer par' ') le motif correspondant le plus court (ici représenté par un espace d'échappement' \ ' à la fin du paramètre PARAMETER - ici nommé STRla source
Comme nous pouvons également utiliser php en ligne de commande, ou des scripts shell. C'est parfois utile pour l'analyse syntaxique chirurgicale.
Avec tuyauterie:
la source
En ksh:
la source