Проверьте, не существует ли строка в нескольких массивах - PullRequest
0 голосов
/ 17 января 2019

Попытка проверить и посмотреть, не является ли строковое значение НЕ членом двух разных массивов. Если строковое значение не существует ни в одном из них, тогда мне нужно выполнить инструкцию. Я смог сделать это с помощью оператора if ....

if [[ $REQ_FIELDS_LIST != *"$XFR_FIELD"* && $NON_INPUT_FIELDS_LIST != *"$XFR_FIELD"* ]];then

Но звездочка заставляет подстроки возвращать ложные срабатывания. К сожалению, удаление «*» и оператора if просто не работает вообще. Проверяя этот сайт, кажется, что единственный БЕЗОПАСНЫЙ способ сделать это в bash - сделать цикл for. Но что является наиболее эффективным способом сделать это для двух разных массивов. Кроме того, строковое значение является членом самого массива. Итак, мы уже перебираем массив. Переберите массив строковых значений и для каждого строкового значения проверьте, не является ли эта строка членом двух других массивов. Если это так, то выполните заявление.

Так что мне нужно ...

for XFR_FIELD in $INPUT_FIELDS_LIST
do
    if XFR field is not a member of REQ_FIELDS_LIST AND is not a member of NON_INPUT_FIELDS_LIST then
        "return 0" 

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Эффективный подход заключается в использовании ассоциативных массивов bash 4.0:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Requires bash 4.0+" >&2; exit 1;; esac

declare -A input_fields_list=( [one]=1 [two]=1 [three]=1 [four]=1 [five]=1 )
declare -A req_fields_list=( [one]=1 [six]=1 [seven]=1 [eight]=1 )
declare -A non_input_fields_list=( [two]=1 [three]=1 [seven]=1 [eight]=1 [nine]=1 )

for xfr in "${!input_fields_list[@]}"; do
  [[ ${req_fields_list[$xfr]} ]] && continue
  [[ ${non_input_fields_list[$xfr]} ]] && continue
  echo "$xfr not found" >&2
  exit 1
done

echo "All input fields are valid" >&2
exit 0

Как вы можете видеть на https://ideone.com/IhmVKy,, это корректно завершается с five not found.

0 голосов
/ 17 января 2019

Вы можете проверить, находится ли элемент в массиве с чем-то вроде этого, без циклов и не подвержен пробелам в элементах

#! /bin/bash
function elem_in_array() {
    local e="$1"
    shift
    local a=("$@")
    [[ $(printf '\x01%s\x01' "${a[@]}") =~ $(printf '\x01%s\x01' "$e") ]]
}

a1=(A B "C D" E F)
elem_in_array "A" "${a1[@]}" && echo Y || echo N
elem_in_array "B" "${a1[@]}" && echo Y || echo N
elem_in_array "C D" "${a1[@]}" && echo Y || echo N
elem_in_array "AB" "${a1[@]}" && echo Y || echo N
0 голосов
/ 17 января 2019

В качестве примера вы могли бы повторить так:

#!/bin/bash

INPUT_FIELDS_LIST=( one two three four five)
REQ_FIELDS_LIST=( one six seven eight )
NON_INPUT_FIELDS_LIST=( two three seven eight nine )

for ifl in "${INPUT_FIELDS_LIST[@]}"
do

        for rfl in "${REQ_FIELDS_LIST[@]}"
        do
                myvar=0
                if [[ $ifl == "$rfl" ]]
                then myvar=1; break
                else continue
                fi
        done

        for nifl in "${NON_INPUT_FIELDS_LIST[@]}"
        do
                myvar2=0
                if [[ $ifl == "$nifl" ]]
                then myvar2=1; break
                else continue
                fi
        done

        if [[ $myvar == 1 ]] || [[ $myvar2 == 1 ]]
        then continue
        else echo "$ifl"
        fi

done

Итерируйте вторичные циклы вручную, а затем помечайте их как недействительные.

оператор if в конце проверяет, было ли сопоставлено какое-либо значение, если оно имеет, оно переходит к следующей основной итерации.

Выход:

four
five
...