Je veux voir si une chaîne est à l'intérieur ne partie d'une autre chaîne.
par exemple.:
'ab' in 'abc' -> true
'ab' in 'bcd' -> false
Comment puis-je faire cela dans les conditions d'un script bash?
Vous pouvez utiliser le formulaire ${VAR/subs}
où VAR
contient la plus grande chaîne et subs
est la sous-chaîne que vous essayez de trouver:
my_string=abc
substring=ab
if [ "${my_string/$substring}" = "$my_string" ] ; then
echo "${substring} is not in ${my_string}"
else
echo "${substring} was found in ${my_string}"
fi
Cela fonctionne parce que ${VAR/subs}
est égal à $VAR
mais que la première occurrence de la chaîne subs
a été supprimée, en particulier si $VAR
ne contient pas le mot subs
, il ne sera pas modifié.
[[ "bcd" =~ "ab" ]]
[[ "abc" =~ "ab" ]]
les crochets sont pour le test, et comme il s'agit de doubles crochets, il peut donc contenir des tests supplémentaires comme =~
.
Donc, vous pouvez utiliser ce formulaire quelque chose comme
var1="ab"
var2="bcd"
if [[ "$var2" =~ "$var1" ]]; then
echo "pass"
else
echo "fail"
fi
Edit: corrigé "= ~", s'était retourné.
Utilisation de bash modèles de nom de fichier (également appelés modèles "glob")
substr=ab
[[ abc == *"$substr"* ]] && echo yes || echo no # yes
[[ bcd == *"$substr"* ]] && echo yes || echo no # no
Les deux approches suivantes fonctionneront sur n’importe quel environnement compatible POSIX, pas seulement en bash:
substr=ab
for s in abc bcd; do
if case ${s} in *"${substr}"*) true;; *) false;; esac; then
printf %s\\n "'${s}' contains '${substr}'"
else
printf %s\\n "'${s}' does not contain '${substr}'"
fi
done
substr=ab
for s in abc bcd; do
if printf %s\\n "${s}" | grep -qF "${substr}"; then
printf %s\\n "'${s}' contains '${substr}'"
else
printf %s\\n "'${s}' does not contain '${substr}'"
fi
done
Les deux sorties ci-dessus:
'abc' contains 'ab'
'bcd' does not contain 'ab'
Le premier a l’avantage de ne pas générer un processus séparé grep
.
Notez que j'utilise printf %s\\n "${foo}"
au lieu de echo "${foo}"
parce que echo
pourrait modifier ${foo}
s'il contient des barres obliques inverses.
Ceci est la solution la plus portable, fonctionnera même sur les vieux obus Bourne et Korn Shell
#!/bin/bash
case "abcd" in
*$1*) echo "It's a substring" ;;
*) echo "Not a substring" ;;
esac
Échantillon échantillon:
$ ./case_substr.sh "ab"
It's a substring
$ ./case_substr.sh "whatever"
Not a substring
Notez que vous n'avez pas à utiliser spécifiquement echo
, vous pouvez utiliser exit 1
et exit 0
pour indiquer un succès ou un échec.
Ce que nous pourrions aussi faire, c’est créer une fonction (qui peut être utilisée dans de gros scripts si nécessaire) avec des valeurs de retour spécifiques (0 sur correspondance, 1 sur absence de correspondance):
$ ./substring_function.sh
ab is substring
$ cat substring_function.sh
#!/bin/sh
is_substring(){
case "$2" in
*$1*) return 0;;
*) return 1;;
esac
}
main(){
if is_substring "ab" "abcdefg"
then
echo "ab is substring"
fi
}
main $@
$ grep -q 'ab' <<< "abcd" && echo "it's a substring" || echo "not a substring"
it's a substring
Cette approche particulière est utile avec les instructions if-else dans bash
. Aussi principalement portable
$ awk '$0~/ab/{print "it is a substring"}' <<< "abcd"
it is a substring
$ python -c 'import sys;sys.stdout.write("it is a substring") if "ab" in sys.stdin.read() else exit(1)' <<< "abcd"
it is a substring
$ Ruby -e ' puts "is substring" if ARGV[1].include? ARGV[0]' "ab" "abcdef"
is substring
Observez les [[
et "
:
[[ $a == z* ]] # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).
[ $a == z* ] # File globbing and Word splitting take place.
[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).
Donc, comme @glenn_jackman l'a dit, mais sachez que si vous mettez tout le second terme entre guillemets, le test passera à correspondance littérale .
Semblable à la réponse d’edwin, mais avec une portabilité améliorée pour posix & ksh, et un toucher moins bruyant que celui de Richard:
substring=ab
string=abc
if [ "$string" != "${string%$substring*}" ]; then
echo "$substring IS in $string"
else
echo "$substring is NOT in $string"
fi
string=bcd
if [ "$string" != "${string%$substring*}" ]; then
echo "$string contains $substring"
else
echo "$string does NOT contain $substring"
fi
Sortie:
abc contains ab
bcd does NOT contain ab