我有一个
array1 = (20,30,40,50)
array2 = (10,20,30,80,100,110,40)
我必须从数组 3 中的这两个数组中获取公共值,例如:
array3 = (20,30,40)
按升序排列。
Shell 和标准 Unix 实用程序擅长处理文本文件。
在那个领域,数组将是文本文件,其元素是行。
要找到两个这样的数组之间的共同部分,可以使用标准comm
命令。comm
期望按字母顺序排序的输入。
因此,如果您有两个文件A
并B
包含这两个数组的元素,每行一个(这也意味着数组元素不能包含换行符),您可以找到与
comm -12 <(sort A) <(sort B)
如果您想从数组开始(但在 shell 中使用数组通常表明您使用了错误的工具来完成任务),您可以在数组和我们的文本文件数组之间bash
来回转换分裂:bash
printf '%s\n'
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)))
您几乎可以肯定不应该为此使用 shell,所以这里有一个针对您的特定问题的 awk 解决方案:
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
如果你告诉我们你真正想要做什么,你可以获得更多帮助。
使用数组的纯bash解决方案:
#!/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[*]}
输出
20 30 40
由于array3
不是关联数组,因此索引使用${!array[*]}
符号升序排列。如果您需要逗号分隔的列表作为输入,请使用echo "${array3[*]}"
.
如果源元素是整数,则可以使用它。它仅在每个源数组都包含唯一编号时才有效。
除了这些好的答案之外,您似乎还想按升序对数组(包含答案)进行排序。
您可以通过多种不同的方式做到这一点,包括:
readarray array3 <<<"$(printf "%s\n" "${array3[@]}" | sort -n)"
此方法还允许您过滤掉重复值:
readarray array3 <<<"$(printf "%s\n" "${array3[@]}" | sort -n | uniq)"
为了练习,这里还有另一种解决方法:
#!/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[@]}
这是使用标准命令行工具(sort
和join
)的解决方案:
join <(printf %s\\n "${array1[@]}" | sort -u) \
<(printf %s\\n "${array2[@]}" | sort -u) | sort -n
join
要求对其输入进行排序,并且不识别数字排序顺序。因此,我以默认排序顺序对两个列表进行排序,将它们连接起来,然后以数字方式对结果进行排序。
我还假设您将数组真正创建为数组,即:
array1=(20 30 40 50)
我认为其余的或多或少是不言而喻的,可能在 and 的帮助help printf
下man bash
。
也许您可以使用 perl 进行尝试。
#!/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
考虑使用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])