Reputation: 447
I have an array with subdirs and files:
~$ array=(elem1/a elem1/b elem2/a elem2/b)
I need to select all files (with its subdir) inside subdir elem1.
I've tried with a for loop and case:
for element in "${array[@]}"; do
case $element in
elem1*)
# action I need to perform on this element
echo "This is $element"
;;
esac
done
I'd like to get the list of elements I need using some glob, in a similar way as this (which substracts substrings from array elements):
~$ echo ${array[@]%/a}
elem1 elem1/b elem2 elem2/b
My main concern is that I shoudn't hardcode what strings I'm searching for, as I don't know its contents - in my final version of this script I'm getting them from another array.
Upvotes: 1
Views: 2415
Reputation: 3125
My answer prints every element of the array in a different line, then filters the ones you are interested (grep
) and put them into a new array
newarray=( $(printf "%s\n" "${array[@]}" | grep ^elem/) )
The only problem would be if the elements of your array (subdirs and file namews) might contain EOL or blank chars.
Bonus
If your elements contain EOL or blank chars, you should use the NUL (\000
) char and grep -zZ
to handle it; but then you need more code to turn out those NUL-char strings into something which the bash can work with -- the bash stops reading when it finds a NUL char.
In this example I use awk
, which has no problem to handle NUL chars, and makes unnecessary the use of grep
:
eval newarray=( $(printf "%s\000" "${A[@]}" |
awk 'BEGIN { FS="\000" }
/^elem\// {
gsub("\042","\\\042")
printf("[" NR-1 "]=\042%s\042 ",$0)
}'
)
)
Upvotes: 2
Reputation: 18697
You can filter your array with a variable query (prefix
below) and store the results in a new array (result
):
#!/bin/bash
array=(elem1/a elem1/b elem2/a elem2/b)
prefix=elem1
result=()
for element in "${array[@]}"; do
[[ $element == $prefix/* ]] && result+=("$element")
done
The result is:
$ declare -p result
declare -a result='([0]="elem1/a" [1]="elem1/b")'
Upvotes: 2
Reputation: 67507
here is one alternative
$ for e in "${array[@]}";
do case "${e%%/*}" in
elem1) echo "$e is in elem1" ;;
esac
done
elem1/a is in elem1
elem1/b is in elem1
Upvotes: 1