I have below shell script in which I have two arrays number1
and number2
. I have a variable range
which has list of numbers.
Now I need to figure out what are all numbers which are in number1
array are also present in range
variable. Similarly for number2
array as well. Below is my shell script and it is working fine.
number1=(1220 1374 415 1097 1219 557 401 1230 1363 1116 1109 1244 571 1347 1404)
number2=(411 1101 273 1217 547 1370 286 1224 1362 1091 567 561 1348 1247 1106 304 435 317)
range=90,197,521,540,552,554,562,569:570,573,576,579,583,594,597,601,608:609,611,628,637:638,640:641,644:648
range_f=" "$(eval echo $(echo $range | perl -pe 's/(\d+):(\d+)/{$1..$2}/g;s/,/ /g;'))" "
echo "$range_f"
for item in "${number1[@]}"; do
if [[ $range_f =~ " $item " ]] ; then
new_number1+=($item)
fi
done
echo "new list: ${new_number1[@]}"
for item in "${number2[@]}"; do
if [[ $range_f =~ " $item " ]] ; then
new_number2+=($item)
fi
done
echo "new list: ${new_number2[@]}"
Is there any better way to write above stuff? As of now I have two for loops iterating and then figuring out new_number1
and new_number2
arrays.
Note: Numbers like 644:648
means, it starts with 644 and ends with 648. It is just short form.
You can use comm
with process substitution instead of looping:
mapfile -t new_number1 < <(comm -12 <(printf '%s\n' "${number1[@]}" | sort) <(printf '%s\n' $range_f | sort))
mapfile -t new_number2 < <(comm -12 <(printf '%s\n' "${number2[@]}" | sort) <(printf '%s\n' $range_f | sort))
mapfile -t name
reads from the nested process substitution into the named array printf ... | sort
printf ... | sort
pair provides the sorted input streams for comm comm -12
emits the items common to the two streams Aside from codeforester's answer, I can think of two other ways of doing this:
$range
as keys of an associative array. The values will be 1
. Loop through each member of ${number1[@]}
and ${number2[@]}
, testing them against the values in the associative array. printf ... | sort
printf ... | sort
trick, but pipe both the list and the range through sort | uniq -c
sort | uniq -c
, then grep for the duplicates. I'm not sure if either one of these is an actual improvement on your code. ... I would create a 'find duplicates' shell function, but otherwise your code looks solid.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.