Comment puis-je écrire un script shell qui fera une correspondance de sous-chaîne insensible à la casse de la sortie de la commande?
shell-script
shell
string
Miguel Roque
la source
la source
grep -i
peut être?bash
, qui est un surensemble de la norme unixsh
. Vous pouvez commencer par regarder l'un de ces éléments: | 1 | | 2 | - juste pour avoir une idée du contexte réel.Réponses:
Voici d'abord un exemple de script simple qui n'ignore pas la casse:
Essayez de changer la chaîne bonjour à droite, et elle ne devrait plus résonner
it works
. Essayez de remplacerecho hello
par une commande de votre choix. Si vous souhaitez ignorer la casse et qu'aucune chaîne ne contient de saut de ligne, vous pouvez utiliser grep:La clé ici est que vous dirigez une sortie de commande vers
grep
. L'if
instruction teste l'état de sortie de la commande la plus à droite dans un pipeline - dans ce cas grep. Grep sort avec succès si et seulement s'il trouve une correspondance.L'
-i
option de grep dit d'ignorer la casse.L'
-q
option dit de ne pas émettre de sortie et de quitter après la première correspondance.L'
-F
option dit de traiter l'argument comme une chaîne plutôt que comme une expression régulière.Notez que le premier exemple utilise ce qui permet des comparaisons directes et divers opérateurs utiles. Le second formulaire exécute simplement les commandes et teste leur état de sortie.
[ expression ]
la source
==
n'est pas POSIX.sh
n'est pasbash
sur tous les systèmes basés sur Linux.==
n'est pas pris en charge parash
(sur lequelsh
est basé au moins de nombreux BSD et dérivés Debian), ouposh
, et doit être cité danszsh
. Il est inutile de doubler le=
.[
est une commande de test. Il n'est pas nécessaire de lever l'ambiguïté entre affectation et comparaison ici. C'est différent(( a == b ))
vs(( a = b))
. L'utilisation==
dans un script qui commence par#! /bin/sh
est incorrecte. Si vous supposezksh
ou labash
syntaxe, mettez à jour en#!
conséquence.Vous pouvez effectuer une correspondance de sous-chaîne insensible à la casse de manière native en
bash
utilisant l'opérateur regex=~
si vous définissez l'nocasematch
option shell. Par exemplela source
[[ XYZ == xyz ]] && echo "match"
=>match
Pour une recherche de chaîne sensible à la casse de la valeur de la variable
needle
dans la valeur de la variablehaystack
:Pour une recherche de chaîne insensible à la casse, convertissez les deux dans la même casse.
Notez que
tr
dans GNU coreutils ne prend pas en charge les paramètres régionaux multi-octets (par exemple UTF-8). Pour faire fonctionner les locales multi-octets, utilisez plutôt awk. Si vous allez utiliser awk, vous pouvez lui faire faire la comparaison de chaînes et pas seulement la conversion.Le
tr
de BusyBox ne prend pas en charge la syntaxe; vous pouvez utiliser à la place. BusyBox ne prend pas en charge les paramètres régionaux non ASCII.[:CLASS:]
tr a-z A-Z
Dans bash (mais pas sh), la version 4.0+, il existe une syntaxe intégrée pour la conversion de casse et une syntaxe plus simple pour la correspondance des chaînes.
la source
printf | tr
me fait tourner la tête. Dans la mesure du possible, gardez votre appel de commandes à un minimum ... étant donné une variable v, vous pouvez accomplir la même chose en utilisantv=$(tr '[:lower:]' '[:upper:]' <<<$v)
. Pour ceux qui ne l'ont jamais vu auparavant, le<<<
est essentiellement une "variable ici" comme l'utilisation de l'<<EOF
est pour un document ici. Ne le faites pasprintf
ou àecho
moins que vous ne deviez absolument le faire.<<<
opérateur: ksh, bash, zsh, mais pas plain sh. Et c'est assez proche de la tuyauterieprintf
en termes de fonctionnement: il y a le même nombre d'appels versfork
etexecve
(en supposant que celaprintf
soit intégré, ce qui est le cas sur la plupart des shells); une différence est que<<<
crée un fichier temporaire plutôt que d'utiliser un canal.<<<
est pratique à taper mais pas une amélioration des performances.