私はbashスクリプトを使用しており、カンマで区切られた値文字列がありますstring="string1,string2,string"
。各文字列にはコンマやスペースは含まれていません。文字列要素が配列にあるかどうかをテストしたいと思います。
文字列要素を任意の配列の要素と一致させるには?
string="element1,element2,element3"
array=($(echo $string | tr ',' ' '))
for i in "${array[@]}"; do
if [ "$i" == "element2" ]; then
echo "element found"
fi
done
答え1
おそらく次のようにすることができます:
string=element1,element2,element3
element=element2
case ",$string," in
(*,"$element",*) echo element is in string;;
(*) echo it is not;;
esac
(標準sh
構文).
配列操作や文字列分割の場合、bashはシェルの中で最悪の選択肢の1つです。
zsh
特定の区切り文字に文字列を分割するには、専用の演算子であるs
plitがあります。パラメータ拡張フラグ:
array=( "${(@s[,])string}" )
(Bourneシェルの@
ように空の要素を保存するために引用符を使用)"$@"
配列に与えられた要素があることを確認してください。
if (( $array[(Ie)$element] )); then
print element is in the array
else
print it is not
fi
分割するには、ksh / shのように、bash
分割+glob演算子(引用符なしで使用するのは少し厄介です)を使用できます。$(...)
IFS=, # split on , instead of the default of SPC/TAB/NL
set -o noglob # disable the glob part which you don't want
array=( $string'' ) # split+glob; '' added to preserve an empty trailing element
# though that means an empty $string is split into one empty
# element rather than no element at all
配列を見つけるためにbashには専用の演算子はありませんが、ヘルパー関数を定義できます。
is_in() {
local _i _needle="$1"
local -n _haystack="$2"
for _i in "${_haystack[@]}"; do
[ "$_i" = "$_needle" ] && return
done
false
}
if is_in "$element" array; then
echo element is in the array
else
it is not
fi
答え2
有効な単語リストのハッシュテーブルを設定し、(効果的に)2番目のリストのすべての項目を検索できます。
#! /bin/bash
#.. ./LookUp 04-Feb-2023: Paul_Pedant.
declare -A Hash #.. Create at global scope.
Setup () { #.. Set up a hash table of the required elements.
local j; declare -a q
#.. Make the input string into an array like: q=([0]="Monday" ...)
IFS=, read -r -a q <<<"${1}"
#.. Invert that array like: Hash([Monday]="0" ...)
for j in "${!q[@]}"; do Hash+=(["${q[j]}"]="${j}"); done
}
Query () { #.. Search for words in a list.
local s; declare -a q
IFS=, read -r -a q <<<"${1}"
for s in "${q[@]}"; do
if [[ -z "${Hash[${s}]+x}" ]]; then
printf '%s is missing\n' "${s}"
else
printf '%s is index %s\n' "${s}" "${Hash[${s}]}"
fi
done
}
Setup "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"
Query "Tuesday,BadHairDay,Friday,Holiday,Sunday,Today,Monday,BadDay"
そしてテストしてください:
$ ./LookUp
Tuesday is index 1
BadHairDay is missing
Friday is index 4
Holiday is missing
Sunday is index 6
Today is missing
Monday is index 0
BadDay is missing
$
答え3
あなたの質問を正しく理解し、csvを配列に変換するビットを無視すると、次のようになります。時々配列内の要素を検索するのに役立ちますが、潜在的な空白/改行文字やその他の文字に関していくつかの注意があります。
arr=(foo bar baz)
if [[ "${arr[*]}" =~ foo ]]; then
echo "element found"
fi
答え4
私は次の解決策を持っています
aggr=("bash" "resource" "rsync")
ukeys="resource,rsync"
if [[ "${aggr[@]}" =~ $(echo "$ukeys" | tr ',' '|') ]]; then
echo "All strings exist in the array."
else
echo "One or more strings do not exist in the array."
fi
このtr
コマンドは、文字列のカンマをパイプで置き換えて、=~
演算子で使用できる正規表現を生成するコマンドを使用します。この$( ... )
構文は tr コマンドを実行して出力をキャプチャするために使用され、その後=~
演算子のパターンとして使用されます。正規表現が配列の要素と一致すると、配列内のすべての文字列が配列内にあることを示すifブロックが実行されます。
ukeys
の要素がarrayの要素と一致するaggr
場合display=1
。