Get common values ​​in 2 arrays in shell scripts

I have

array1 = (20,30,40,50) array2 = (10,20,30,80,100,110,40) 

I need to get common values ​​from these 2 arrays in my array 3, for example:

 array3 = (20,30,40) 

in ascending sort order.

+4
source share
7 answers

Shell and standard Unix utilities are well versed in text files.

In this area, arrays will be text files whose elements are strings.

To find a common part between two such arrays, there is a standard comm command. comm expects a selection in alphabetical order though.

So, if you have two files A and B containing the elements of these two arrays, one per line (which also means that the elements of the array cannot contain newlines), you can find the intersection with

 comm -12 <(sort A) <(sort B) 

If you want to start with bash arrays (but using arrays in shells is usually a good indicator that you are using the wrong tool for your task), you can convert back and forth between bash arrays and our text string arrays with printf '%s\n' and word splitting:

 array_one=(20 30 40 50) array_two=(10 20 30 80 100 110 40) IFS=$'\n'; set -f intersection=($(comm -12 <( printf '%s\n' "${array_one[@]}" | sort) <( printf '%s\n' "${array_two[@]}" | sort))) 
+3
source

Pure bash using arrays

 #!/bin/bash array1=(20,30,40,50) array2=(10,20,30,80,100,110,40) IFS=, for i in $array1 $array2;{ ((++tmp[i]));} for i in ${!tmp[*]};{ [ ${tmp[i]} -gt 1 ] && array3+=($i);} echo ${array3[*]} 

Output

 20 30 40 

Since array3 not an associative array, the indices come in ascending order using the notation ${!array[*]} . If you need a comma separated list as input, use echo "${array3[*]}" .

It can be used if the source elements are integers. It only works if each of the source arrays contains unique numbers.

+2
source

You almost certainly shouldn't use a wrapper for this, so here is ONE awk solution for your specific problem:

 awk 'BEGIN{ split("20,30,40,50",array1,/,/) split("10,20,30,80,100,110,40",array2,/,/) for (i=1;i in array1;i++) for (j=1;j in array2;j++) if (array1[i] == array2[j]) array3[++k] = array1[i] for (k=1; k in array3; k++) printf "array3[%d] = %d\n",k,array3[k] }' array3[1] = 20 array3[2] = 30 array3[3] = 40 

and if you tell us what you are really trying to do, you can get a lot more help.

+2
source

Consider using python:

 In [6]: array1 = (20,30,40,50) In [7]: array2 = (10,20,30,80,100,110,40) In [8]: set(array1) & set(array2) Out[8]: set([40, 20, 30]) 
+1
source

In addition to any of these great answers, it seems like you also want to sort your array (containing the answer) in ascending order.

You can do this in several ways, including:

 readarray array3 <<<"$(printf "%s\n" "${array3[@]}" | sort -n)" 

This method also allows you to filter out duplicate values:

 readarray array3 <<<"$(printf "%s\n" "${array3[@]}" | sort -n | uniq)" 

And for the sake of exercise, here is another way to solve it:

 #!/bin/bash array1=(20 30 40 50) array2=(10 20 30 80 100 110 40) declare -a array3 #sort both arrays readarray array1 <<<"$(printf "%s\n" "${array1[@]}" | sort -n)" readarray array2 <<<"$(printf "%s\n" "${array2[@]}" | sort -n)" # look for values i2=0 for i1 in ${!array1[@]}; do while (( i2 < ${#array2[@]} && ${array1[$i1]} > ${array2[$i2]} )); do (( i2++ )); done [[ ${array1[$i1]} == ${array2[$i2]} ]] && array3+=(${array1[$i1]}) done echo ${array3[@]} 
0
source

There is a solution with standard command line tools ( sort and join ):

 join <(printf %s\\n "${array1[@]}" | sort -u) \ <(printf %s\\n "${array2[@]}" | sort -u) | sort -n 

join requires its inputs to be sorted and not recognize the numerical sort order. Therefore, I sort both lists in the default sort order, join them and then return the result numerically.

I also suggested that you created arrays really like arrays, i.e.:

 array1=(20 30 40 50) 

I think the rest is more or less self-evident, perhaps with help printf and man bash .

0
source

maybe you can use perl for try.

 #!/bin/perl use warnings; use strict; my @array1 = (20,30,40,50); my @array2 = (10,20,30,80,100,110,40); my @array3 = (); foreach my $x (@array1) { # body... if (grep(/$x/, @array2)){ print "found $x\n"; @array3=(@array3,$x); }; } print @array3 
0
source

Source: https://habr.com/ru/post/1485519/


All Articles