1
votes

Comment déterminer si $ var est un présent dans un tableau en tant que mot complet

J'ai le problème suivant: J'ai un tableau array = (test3 testtest) . Maintenant, j'ai une variable var et je veux tester si var n'est pas présent dans le tableau, mais ne correspond qu'à des mots complets: Exemple:

test3 would match
test not

J'ai déjà le code suivant, qui fonctionne pour trouver les occurrences, mais pas pour les mots complets uniquement, test est trouvé comme une correspondance: si! [[$ {array [*]} = ~ test]]; puis echo "Not in"; fi J'ai une seconde tentative pour y parvenir, mais avec ce code, test3 ne se trouve pas non plus: si! [[$ {array [*]} = ~ \ ]]; puis echo "Not in"; fi Je veux y parvenir, sans aucune boucle si cela est possible. Ma question est donc: Est-il possible de le faire sans aucune boucle? Si ce n'est pas le cas, comment puis-je faire cela avec une boucle? Mon problème est que cette instruction if est déjà dans une boucle existante, définissant des valeurs pour var . Donc, si j'ai une boucle dans une boucle, ce qui je pense, ce n'est pas très bon.


0 commentaires

5 Réponses :


0
votes

Je ne comprends pas tout à fait ce que vous demandez, mais le code suivant vous aide-t-il? Il recherche les éléments dans array0 et les compare avec des mots entiers dans array1

#!/bin/bash
array0=(test3 testtest)
array1=(testtest bla test3)

for i in "${array1[@]}"; do
        echo -ne "$i: \t"
        if ! [[ ${array0[*]} =~ ([[:space:]]|^)$i([[:space:]]|$) ]]; then
                echo "Not in"; 
        else
                echo "Yes in";
        fi
done
exit 0

Pour effectuer une correspondance avec des mots entiers, vous devez envelopper la chaîne avec ([[: space:]] | ^) et ([[: space:]] | $) . Cela permet au mot d'être entouré d'espaces, ou d'exister au début ( ^ ) ou à la fin ( $ ) de la ligne.

p>


1 commentaires

les espaces l'ont fait, merci. j'utilise maintenant: si! [["$ {array [@]}" = ~ "test"]]; puis



0
votes

Cela semblait fonctionner avec le code que vous avez fourni dans le message précédent.

Voici ma sortie:

test3 testtest

Dans le tableau

Voici le code exact que j'ai utilisé:

array=(test3 testtest)
echo ${array[*]}

if ! [[ ${array[*]} =~ test ]];
then echo "Not in Array";
else echo 'In Array';
fi


1 commentaires

La solution que vous avez fournie vérifie si la chaîne «test» est présente dans le tableau. @ TNT2k demande une correspondance exacte des mots. Où «test3» correspondrait mais «test» ne correspond pas. Avez-vous une solution alternative pour cela?



0
votes

Essayez un tableau associatif pour la recherche.

$: declare -A lookup=()
$: list=( test3 would match )
$: for item in "${list[@]}"; do lookup[$item]=1; done

$: [[ -n "${lookup[test]}" ]] && echo found || echo nope 
nope

$: [[ -n "${lookup[test3]}" ]] && echo found || echo nope 
found

Cela n'a pas beaucoup de valeur si le tableau n'est pas assez stable, car vous ' Je dois continuer à le reconstruire. Dans ce cas, vous pouvez tout aussi bien utiliser une boucle de force brute.


0 commentaires

0
votes

Peut-être pas joli, mais je pense que cela fonctionnera comme une condition:

printf '%s\n' "${array[@]}" | grep -q -e '^test$'

... en supposant que les membres du tableau ne peuvent pas avoir de nouvelles lignes.


0 commentaires

0
votes

Il suffit d'utiliser une boucle.

# Exit status 0 if the argument is not one of the array elements.
# Exit status 1 as soon as a match is found.
match () {
  for x in "${array[@]}"; do
    [[ $1 = "$x" ]] && return 1
  done
  return 0
}

L'intérêt d'un tableau est de fournir un conteneur capable de distinguer deux éléments sans utiliser aucun type de délimiteur. L'aplatissement du tableau avec [*] supprime cette garantie.


2 commentaires

le but est de ne pas utiliser de boucle, voir mon explication ci-dessous le bloc de code


Eh bien, j'ai maintenant une solution sans boucle, et cela fonctionne très bien. Le var ne contiendra pas d'espaces ou de caractères spéciaux et autres, car ce n'est que le nom d'une image docker :)