Comment comparer les chaînes dans Bourne Shell?
Question
Je dois comparer les chaînes dans le shell:
var1="mtu eth0"
if [ "$var1" == "mtu *" ]
then
# do something
fi
Mais évidemment, le " * " ne fonctionne pas dans Shell. Y a-t-il un moyen de le faire?
La solution
bash
Correctif le plus court:
if [[ "$var1" = "mtu "* ]]
Le [[]]
de Bash n'est pas globalement développé, contrairement à []
(qui doit, pour des raisons historiques).
bash --posix
Oh, j'ai posté trop vite. Bourne shell, pas Bash ...
if [ "${var1:0:4}" == "mtu " ]
$ {var1: 0: 4}
signifie les quatre premiers caractères de $ var1
.
/ bin / sh
Ah, désolé. L'émulation POSIX de Bash ne va pas assez loin; Un véritable shell Bourne d'origine n'a pas $ {var1: 0: 4}
. Vous aurez besoin de quelque chose comme la solution de mstrobl.
if [ "$(echo "$var1" | cut -c0-4)" == "mtu " ]
Autres conseils
Utilisez les outils Unix. Le programme cut
raccourcira volontiers une chaîne.
if [ "$(echo $var1 | cut -c 4)" = "mtu " ];
... devriez faire ce que vous voulez.
Vous pouvez appeler expr
pour faire correspondre les chaînes aux expressions régulières à partir de scripts Bourne Shell. Ce qui suit semble fonctionner:
#!/bin/sh
var1="mtu eth0"
if [ "`expr \"$var1\" : \"mtu .*\"`" != "0" ];then
echo "match"
fi
Je ferais ce qui suit:
# Removes anything but first word from "var1"
if [ "${var1%% *}" = "mtu" ] ; then ... fi
Ou:
# Tries to remove the first word if it is "mtu", checks if we removed anything
if [ "${var1#mtu }" != "$var1" ] ; then ... fi
Dans Bourne Shell, si je souhaite vérifier si une chaîne contient une autre chaîne:
if [ `echo ${String} | grep -c ${Substr} ` -eq 1 ] ; then
Joignez echo $ {String} | grep -c $ {Substr}
avec deux backticks `
:
Pour vérifier si la sous-chaîne est au début ou à la fin:
if [ `echo ${String} | grep -c "^${Substr}"` -eq 1 ] ; then
...
if [ `echo ${String} | grep -c "${Substr}<*>quot;` -eq 1 ] ; then
J'aime utiliser l'instruction case pour comparer des chaînes.
Un exemple trivial est
case "$input"
in
"$variable1") echo "matched the first value"
;;
"$variable2") echo "matched the second value"
;;
*[a-z]*) echo "input has letters"
;;
'') echo "input is null!"
;;
*[0-9]*) echo "matched numbers (but I don't have letters, otherwise the letter test would have been hit first!)"
;;
*) echo "Some wacky stuff in the input!"
esac
J'ai fait des choses folles comme
case "$(cat file)"
in
"$(cat other_file)") echo "file and other_file are the same"
;;
*) echo "file and other_file are different"
esac
Et cela fonctionne aussi, avec certaines limitations, telles que les fichiers ne peuvent pas dépasser deux mégaoctets et que le shell ne voit tout simplement pas les valeurs NULL. Par conséquent, si un fichier est plein de NULL et que l'autre n'en contient aucun ( et ni rien d'autre), ce test ne verra aucune différence entre les deux.
Je n'utilise pas la comparaison de fichiers comme exemple sérieux, mais un exemple de la façon dont l'instruction case est capable d'effectuer une correspondance de chaîne beaucoup plus flexible que celle disponible avec test ou expr ou d'autres expressions de shell similaires.
Ou, à titre d'exemple de l'opérateur = ~ :
if [[ "$var1" =~ "mtu *" ]]