저는 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는 쉘 중에서 최악의 선택 중 하나입니다.
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
유효한 단어 목록의 해시 테이블을 설정한 다음 (효과적으로) 두 번째 목록의 모든 항목을 검색할 수 있습니다.
#! /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
.