使用“ comm”查找两个数组之间的匹配项

时间:2019-09-25 14:04:09

标签: arrays bash shell

我有两个数组,我正在尝试使用comm查找匹配值。 Array1在我为进行比较而删除的每个元素中都包含一些其他信息。但是,我想在比较完成后保留这些信息。

例如:

Array1=("abc",123,"hello" "def",456,"world")
Array2=("abc")
declare -a Array1
declare -a Array2

然后我比较两个数组:

oldIFS=$IFS IFS=$'\n\t'
array3=($(comm -12 <(echo "${Array1[*]}" | awk -F "," {'print $1'} | sort) <(echo "${Array2[*]}" | sort)))
IFS=$oldIFS

找到abc的匹配项:

echo ${test3[0]}
abc

但是我想要的是array1中剩余的值,这些值不属于我的comm语句。

abc,123,hello

编辑:更多说明

此示例中的数组填充有伪数据。

我的真实示例是从服务器日志中提取信息,并将其保存到array1中。 array1包含要与用户ID列表(array2)交叉引用的(userID,hostIP,计数)。我的目标是找出array1和array2中存在哪些用户ID,并将这些ID与来自array1的其他信息(主机IP,计数)保存到array3

array1由变量生成,该变量是curl命令的结果,该命令生成splunk搜索。返回的数据如下所示:

"uniqueID=<ID>","<IP>","<hostname>",1

我将splunk报告的结果另存为$ splunk,然后使用$ splunk的结果对array1进行十进制处理-标头信息,因为结果以csv格式返回

array1=( $(echo $splunk | sed 's/ /\n/g' | sed 1d) )

array2是从我在本地存储的主文件生成的。包含我们生态系统中的所有应用程序ID。例如

uid=<ID>

我将主文件的内容放入array2

array2=( $(cat master.txt) )

然后,我想找到array2中存在的array1的ID,并将其保存为array3。这需要对array1中的数据进行一些按摩,以使其与array2的格式匹配。

oldIFS=$IFS IFS=$'\n\t'
array3=($(comm -12 <(echo "${array1[*]}" | sed 's/ /\n/g' | awk -F "\"," {'print $1'} | sed 's/\"//g' | sed 's/|/ /g' | awk -F$'=' -v OFS=$'=' '{ $1 = "uid" }1' | grep -i "OU=People" | sed 's/OU/ou/g' | sort) <(echo "${array2[*]}" | sort)))
IFS=$oldIFS

数组3将包含在两个数组中都匹配的行

uid=<ID>
uid=<ID>

但是我正在寻找更多与

相似的东西
"uid=<ID>","<IP>","<hostname>",1
"uid=<ID>","<IP>","<hostname>",1

2 个答案:

答案 0 :(得分:1)

我会这样:

join -t, \
    <(printf '%s\n' "${Array1[@]}" | sort -t, -k1,1) \
    <(printf '%s\n' "${Array2[@]}" | sort)

使用join作为域分隔符使用,命令。第一个“文件”是第一个数组,每行一个元素,在第一个字段上排序(以逗号分隔);第二个“文件”是第二个数组,每行一个元素,已排序。

输出将是第一个文件的第一个元素与第二个文件中的元素相匹配的每一行;对于示例输入,它是

abc,123,hello

这仅作一个假设,即没有数组元素包含换行符。为了使其更健壮(假设使用GNU Coreutils),我们可以使用NUL作为分隔符:

join -z -t, \
    <(printf '%s\0' "${Array1[@]}" | sort -z -t, -k1,1) \
    <(printf '%s\0' "${Array2[@]}" | sort -z)

这也会打印以NUL分隔的输出;要将结果读入数组,我们可以使用readarray

readarray -d '' -t Array3 < <(
    join -z -t, \
        <(printf '%s\0' "${Array1[@]}" | sort -z -t, -k1,1) \
        <(printf '%s\0' "${Array2[@]}" | sort -z)
)

readarray -d需要Bash 4.4或更高版本。对于较旧的Bash,您可以使用循环:

while IFS= read -r -d '' element; do
    Array3+=("$element")
done < <(
    join -z -t, \
        <(printf '%s\0' "${Array1[@]}" | sort -z -t, -k1,1) \
        <(printf '%s\0' "${Array2[@]}" | sort -z)
)

答案 1 :(得分:0)

我不知道如何使用C7来做到这一点,但是我确实为您提供了import random i = random.randint(1, 2) if i == '1': print("hello") if i == '2': print("Hi") comm的解决方案。以下命令在正则表达式sed上匹配,其中字符串/数组分别为grepuid=X,的形式。

uid=x