我正在使用 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 是 shell 中最糟糕的选择之一。
使用zsh
, 要在给定分隔符上分割字符串,有一个专用运算符:s
plit 参数扩展标志:
array=( "${(@s[,])string}" )
(@
以及用于保留空元素的引号,如"$@"
Bourne shell 中的 )
检查数组是否有给定元素:
if (( $array[(Ie)$element] )); then
print element is in the array
else
print it is not
fi
要拆分bash
,您可以使用 split+glob 运算符(使用不带引号的 有点尴尬$(...)
),就像 ksh/sh 中一样:
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
您可以设置有效单词列表的哈希表,然后(有效地)搜索第二个列表中的所有项目。
#! /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块,表明字符串中的所有字符串都存在于数组中。
我想以这样的方式进行调整:如果 in 中的元素与ukeys
array 中的元素匹配aggr
,则我设置display=1
.