string - script - unix sous chaine




La chaîne contient dans Bash (14)

Réponse compatible

Comme il y a déjà beaucoup de réponses utilisant des fonctionnalités spécifiques à Bash, il existe un moyen de travailler sous des shells plus pauvres, comme busybox :

[ -z "${string##*$reqsubstr*}" ]

En pratique, cela pourrait donner:

string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
  if [ -z "${string##*$reqsubstr*}" ] ;then
      echo "String '$string' contain substring: '$reqsubstr'."
    else
      echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
  done

Cela a été testé sous bash , dash , ksh et ash (busybox), et le résultat est toujours:

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

En une seule fonction

Comme demandé par @EeroAaltonen voici une version de la même démo, testé sous les mêmes coquilles:

myfunc() {
    reqsubstr="$1"
    shift
    string="[email protected]"
    if [ -z "${string##*$reqsubstr*}" ] ;then
        echo "String '$string' contain substring: '$reqsubstr'.";
      else
        echo "String '$string' don't contain substring: '$reqsubstr'." 
    fi
}

Alors:

$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.

$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.

Remarque: vous devez vous échapper ou doublez les guillemets et / ou les guillemets:

$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.

$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.

Fonction simple

Cela a été testé sous busybox , dash et, bien sûr, bash :

stringContain() { [ -z "${2##*$1*}" ]; }

C'est tout les gens!

Alors maintenant:

$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes

... Ou si la chaîne soumise pouvait être vide, comme indiqué par @Sjlver, la fonction deviendrait:

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

ou comme suggéré par le commentaire d'Adrian Günter , en évitant -o switche:

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ] ;} ; }

Avec des chaînes vides:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

J'ai une chaîne dans Bash:

string="My string"

Comment puis-je tester s'il contient une autre chaîne?

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

?? est mon opérateur inconnu. Est-ce que j'utilise echo et grep ?

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

Cela a l'air un peu maladroit.


Cela fonctionne aussi:

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

Et le test négatif est:

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

Je suppose que ce style est un peu plus classique - moins dépendant des caractéristiques du shell Bash.

L'argument -- est une pure paranoïa POSIX, utilisée pour protéger contre les chaînes d'entrée similaires aux options, telles que --abc ou -a .

Note: Dans une boucle serrée, ce code sera beaucoup plus lent que l'utilisation de fonctions de shell Bash internes, car un (ou deux) processus séparés seront créés et connectés via des canaux.


Correspondance exacte du mot:

string='My long string'
exactSearch='long'

if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
  then
    echo "It's there"
  fi

Essayez oobash c'est une bibliothèque de chaînes de style OO pour bash 4. Il a un support pour les trémas allemands. Il est écrit en bash. De nombreuses fonctions sont disponibles: -base64Decode , -base64Encode , -base64Decode , -base64Encode , -capitalize , -center , -charAt , -concat , -endsWith , -equals , -equalsIgnoreCase , -reverse , -hashCode , -indexOf , -isAlnum , -isAlpha , -isAscii , -isDigit , -isEmpty , -isHexDigit , -isLowerCase , -isSpace , -isPrintable , -isUpperCase , -isVisible , -lastIndexOf , -length , -matches , -replaceAll , -replaceFirst , -startsWith , -substring , -swapCase , -toLowerCase , -toString , -toUpperCase , -trim et -zfill .

Regardez l'exemple contient:

[Desktop]$ String a testXccc                                                  
[Desktop]$ a.contains tX                   
true                                                           
[Desktop]$ a.contains XtX      
false      

oobash est disponible sur Sourceforge.net .


J'ai souvent besoin de cette fonctionnalité, donc j'utilise comme ça une fonction shell faite maison dans mon .bashrc qui me permet de la réutiliser aussi souvent que nécessaire, avec un nom facile à retenir:

function stringinstring()
{
    case "$2" in 
       *"$1"*)
          return 0
       ;;
    esac   
    return 1
}

Pour tester si $string1 (disons, abc ) est contenu dans $string2 (disons, 123abcABC ), j'ai juste besoin d'exécuter stringinstring "$string1" "$string2" et de vérifier la valeur de retour, par exemple

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

J'aime sed.

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

Modifier, logique:

  • Utilise sed pour supprimer l'instance de sous-chaîne de la chaîne

  • Si la nouvelle chaîne diffère de l'ancienne chaîne, la sous-chaîne existe


Je ne suis pas sûr d'utiliser une instruction if, mais vous pouvez obtenir un effet similaire avec une instruction case:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

L'un est:

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'

Mon .bash_profile et comment j'ai utilisé grep si le PATH incluait mes 2 bin bin, ne pas les ajouter

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

U=~/.local.bin:~/bin

if ! echo "$PATH" | grep -q "home"; then
    export PATH=$PATH:${U}   
fi

Que dis-tu de ça:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi

Vous devriez vous rappeler que les scripts shell sont moins un langage et plus d'une collection de commandes. Instinctivement, vous pensez que ce "langage" vous oblige à suivre un if [ ou un [[ . Les deux sont juste des commandes qui retournent un état de sortie indiquant le succès ou l'échec (comme toutes les autres commandes). Pour cette raison, j'utiliserais grep , et non la [ commande.

Faites juste:

if grep -q foo <<<"$string"; then
    echo "It's there"
fi

Maintenant que vous songez à tester if le statut de sortie de la commande qui le suit (compléter avec un point-virgule). Pourquoi ne pas reconsidérer la source de la chaîne que vous testez?

## Instead of this
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...

## Simply do this
if file -b "$1" | grep -q "tar archive"; then
#...

L'option -q fait que grep ne renvoie rien, car nous voulons seulement le code de retour. <<< fait que le shell développe le mot suivant et l'utilise comme entrée pour la commande, une version d'une ligne du << document ici (je ne suis pas sûr que ce soit standard ou un bashisme).


Vous pouvez utiliser la réponse de Marcus (* caractères génériques) en dehors d'une déclaration de cas, si vous utilisez des doubles crochets:

string='My long string'
if [[ $string = *"My long"* ]]; then
  echo "It's there!"
fi

Notez que les espaces dans la chaîne d'aiguille doivent être placés entre guillemets, et les caractères génériques * doivent être à l'extérieur.


Cette réponse de dépassement de pile était la seule à intercepter l'espace et les tirets:

# For null cmd arguments checking   
to_check=' -t'
space_n_dash_chars=' -'
[[ $to_check == *"$space_n_dash_chars"* ]] && echo found

[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"






substring