2013-06-11 4 views
5

ich über diese kühle Bash Funktion kam zum Prüfen, ob ein Array ein Element enthält:Bash Prüfungselement in der Anordnung für Elemente in einem anderen Array

CONTAINS_ELEMENT(){ 
    local e 
    for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done 
    return 1 
} 

Hier ist ein Beispiel dafür Nutzung ist:

if CONTAINS_ELEMENT $element "${array[@]}"; then 
... 
fi 

Meine Frage ist dies: Gibt es eine Möglichkeit, diese Funktion neu schreiben, so dass es überprüfen kann, ob ein Wert innerhalb einer Array ist gleich einem Wert mit dem anderen Array, und nicht nur nach einem einzigen Wert, wie es corrently tun es?

+0

Nicht korrekt! Probieren Sie '" $ {@: 2} "'. – TrueY

+0

Sehr ähnlich zu Array-Kreuzungsfragen [1] (http://stackoverflow.com/questions/2696055/intersection-of-two-lists-in-bash) und [2] (http://stackoverflow.com/questions/ 7870230/array-intersection-in-bash). – l0b0

+2

Um zu zeigen, dass die Frage gelöst wurde, kreuzen Sie eine der Antworten als "akzeptiert" an. – fedorqui

Antwort

2

KORRIGIERT # 3

Try-Code unten. ArrContains nehmen Sie zwei Argumente, den Namen der beiden Arrays. Es erstellt einen temporären Hash von lArr1 und überprüft dann, ob sich Elemente von lArr2 im Hash befinden. Auf diese Weise können die eingebetteten for-Loops vermieden werden.

#!/usr/bin/bash 

ArrContains(){ 
    local lArr1 lArr2 
    declare -A tmp 
    eval lArr1=("\"\${$1[@]}\"") 
    eval lArr2=("\"\${$2[@]}\"") 
    for i in "${lArr1[@]}";{ ((++tmp['$i']));} 
    for i in "${lArr2[@]}";{ [ -n "${tmp[$i]}" ] && return 0;} 
    return 1 
} 

arr1=("a b" b c) 
arr2=(x 'b c' e) 
arr3=(q a\ b y) 
ArrContains arr1 arr2 && echo Contains arr1 arr2 
ArrContains arr1 arr3 && echo Contains arr1 arr3 

Output:

Contains arr1 arr3 

andere Weise sein könnte einige Trennzeichen und Verketten der ersten Hash zu definieren. Suchen Sie dann nach der Zeichenfolge SEPitemSEP.

ArrContainsRe(){ 
    local lArr1 lArr2 tmp 
    eval lArr1=("\"\${$1[@]}\"") 
    printf -v tmp ",%s" "${lArr1[@]}"; 
    tmp="$tmp," 
    eval lArr2=("\"\${$2[@]}\"") 
    for i in "${lArr2[@]}";{ [[ $tmp =~ ,$i, ]] && return 0;} 
    return 1 
} 
... 
ArrContainsRe arr1 arr2 && echo ContainsRe arr1 arr2 
ArrContainsRe arr1 arr3 && echo ContainsRe arr1 arr3 

Ausgang:

ContainsRe arr1 arr3 
+0

@ l0b0: Sie haben Recht! Die erste Funktion hat es schlecht gehandhabt. Ich korrigierte. Vielen Dank! – TrueY

+0

@ l0b0: Ich wollte nur deinen letzten Kommentar auffrischen, aber es wurde entfernt ...;) Jedenfalls danke für sie! – TrueY

+0

Das schlägt fehl, wenn ich es versuche. Es gibt nichts zurück, egal was. –

-1

Dies sollte es tun:

any_overlap() { 
    for e1 in "${array1[@]}" 
    do 
     for e2 in "${array2[@]}" 
     do 
      if [[ "$e1" = "$e2" ]] 
      then 
       return 0 
      fi 
     done 
    done 
    return 1 
} 

Testsitzung:

$ array1=(foo bar baz) array2=(ban bat bar) && any_overlap; echo $? 
0 
$ array1=(foo bar baz) array2=(ban bat) && any_overlap; echo $? 
1 
$ array1=() array2=() && any_overlap; echo $? 
1 

Natürlich gibt es schnellere Möglichkeiten, es zu tun, wenn der Arrays sortiert ist oder keiner der Array-Elemente Leerzeichen enthalten.

+0

Wie würden Sie zwei Arrays als Parameter nehmen? Es ist nicht möglich. – l0b0

+0

Sie können die Größe des ersten Arrays als ersten Parameter verwenden :-) – choroba

+0

"Wenn die ersten beiden Elemente in den jeweiligen Arrays unterschiedlich sind, wird 0 zurückgegeben." Was meinen Sie? Ich habe es gerade getestet, und es funktioniert gut. – l0b0

0

an den Verbindungen der Suche oben ich eine Lösung kam, die fast tut, was ich brauche, es zu tun, aber nicht ganz:

parameters=($1 $2 $3 $4) 
arg1=(h help -h --help) 

PARAMETERS(){ 
pr1=" $parameters[@]} " 
for item in ${@:1}; do 
    if [[ $pr1 =~ " $item " ]]; then 
    return 0 
    else 
    return 1 
    fi 
done 
} 

if PARAMETERS "${arg1[@]}"; then 
    echo "It works!" 
else 
    echo "Nope, still not working..." 
fi 

Jetzt dieser Code funktioniert, wenn Sie den Parameter "h" übergeben, aber nicht, wenn Sie die anderen Parameter im Array übergeben (-h --help help). Entschuldigung, wenn ich hier einen dummen Fehler mache, bin ich ein bisschen nuub wenn es um Bash Scripting geht :)

+0

Ein Syntaxproblem: 'pr1 =" $ parameters [@]} "' könnte 'pr1 =" $ {parameters [@]} "' sein. Aber ich kann vorschlagen, 'local pr1 = ...' zu verwenden. Und ein Semantikproblem: Das 'if' kehrt in der ersten Schleife in' PARAMETERS' zurück. Ich nehme an, dass der "else" -Teil nicht benötigt wird. – TrueY

+0

Ok, Ihre eigene Lösung hat sich als eine bessere Lösung für mein Problem erwiesen. Danke nochmal für deine Hilfe! –

Verwandte Themen