【问题标题】:How to do index to index value comparison in Unix如何在 Unix 中进行索引到索引值的比较
【发布时间】:2021-08-23 20:35:33
【问题描述】:

我有一个场景,我用 array_2 [index] 值检查了 array_1 [index] 值。

我下面的代码就像一个魅力,但有什么不同的方法可以达到同样的效果吗?

我正在寻找一种独特的方式来处理 2 个数组列表值并进行比较, 只需几行代码。

我的代码:

#!/bin/bash

array_1=(4 4 3)
array_2=(4 1 3)

i=''
j=''

count=0
for i in "${array_1[@]}"
do 
 i="cmd ${array_1[$count]}"
 j="cmd ${array_2[$count]}"
   
     if [ "$i" -eq "$j" ]
     then
           echo "${array_1[$count]} match with ${array_2[$count]}"
           count=$(( count + 1 ))        
     else 
           echo "${array_1[$count]} does not match with ${array_2[$count]}"
           exit 1
     fi 
      
done 

注意:用shellcheck.net检查代码,没有发现错误。

如果两个数组有不同的值,下面是输出:

array_1=(4 4 3)
array_2=(4 1 3)

输出:

4 match with 4
4 does not match with 1

如果两个数组的值相同,则输出如下:

array_1=(4 4 3)
array_2=(4 4 3)

输出:

4 match with 4
4 match with 4
3 match with 3

【问题讨论】:

  • 你应该用你实际使用的 shell 来标记你的问题,而不仅仅是 shell,因为不同的 shell 有非常不同的做事方式。
  • 为什么你有i="cmd ${array_1[$count]}"而不是i="${array_1[$count]}"

标签: bash shell unix awk text-processing


【解决方案1】:

与您最近提出的其他 shell 问题一样,您根本不应该在 shell 中执行此操作,但由于您似乎专注于这样做,以下是您正在做的事情的简单方法(减去确切的输出格式):

$ cat tst.sh
#!/usr/bin/env bash

array_1=(4 4 3)
array_2=(4 1 3)

diff -y <(printf '%s\n' "${array_1[@]}") <(printf '%s\n' "${array_2[@]}")

$ ./tst.sh
4                                                               4
4                                                             | 1
3                                                               3

以下是如何在 shell 中编写问题中的代码(如果您的数组大小不同,您现有的代码将失败):

$ cat tst.sh
#!/usr/bin/env bash

array_1=(4 4 3)
array_2=(4 1 3)

size1=${#array_1[@]}
size2=${#array_2[@]}
if (( size1 > size2 )); then
    maxSize=$size1
else
    maxSize=$size2
fi

for (( i=0; i<maxSize; i++ )); do

     val1=${array_1[i]}
     val2=${array_2[i]}

     if [ "$val1" -eq "$val2" ]
     then
           echo "${array_1[$i]} match with ${array_2[$i]}"
     else
           echo "${array_1[$i]} does not match with ${array_2[$i]}"
           exit 1
     fi

done

$ ./tst.sh
4 match with 4
4 does not match with 1

但更好的方法是:假设您出于某种原因确实需要从 2 个 shell 数组开始:

$ cat tst.sh
#!/usr/bin/env bash

array_1=(4 4 3)
array_2=(4 1 3)

awk -v string_1="${array_1[*]}" -v string_2="${array_2[*]}" '
    BEGIN {
        size1 = split(string_1,array_1)
        size2 = split(string_2,array_2)

        maxSize = (size1 > size2 ? size1 : size2)

        for (i=1; i<=maxSize; i++) {
            val1 = array_1[i]
            val2 = array_2[i]

            if ( val1 == val2 ) {
                printf "%s match with %s\n", array_1[i], array_2[i]
            }
            else {
                printf "%s does not match with %s\n", array_1[i], array_2[i]
                exit 1
            }
        }
    }
'

$ ./tst.sh
4 match with 4
4 does not match with 1

【讨论】:

    【解决方案2】:

    您在问题中添加了awk

    使用awk,您可以这样做:

    awk 'FNR==NR{x[FNR]=$1; next}
         x[FNR]==$1{print x[FNR] " match with " $1; next}
         {print x[FNR] " does not match with " $1}
         ' <(printf "%s\n" "${array_1[@]}") <(printf "%s\n" "${array_2[@]}")
    

    或者使用pasteawk 你可以这样做:

    paste <(printf "%s\n" "${array_1[@]}") <(printf "%s\n" "${array_2[@]}") | awk '
    $1==$2{print $1 " match with " $2; next}
    {print $1 " does not match with " $2}'
    

    打印(在您的示例中使用两个数组):

    4 match with 4
    4 does not match with 1
    3 match with 3
    

    如果你想在第一次不匹配后退出,只需在print之后添加exit即可:

    awk 'FNR==NR{x[FNR]=$1; next}
         x[FNR]==$1{print x[FNR] " match with " $1; next}
         {print x[FNR] " does not match with " $1; exit 1}
         ' <(printf "%s\n" "${array_1[@]}") <(printf "%s\n" "${array_2[@]}")
    

    说明

    printf "%s\n" "${array_1[@]}" 的构造将array_1 的输出创建为由\n 分隔的字符串:

    printf "%s\n" "${array_1[@]}"
    4
    4
    3
    

    结构:

    cmdX <(cmdY)
    

    执行以下操作:

    1. cmdY 和的标准输出在shell 中创建一个匿名的类似文件的fifo 和
    2. 将文件名作为参数输入到类似文件的输出到cmdX,然后作为文件读取。

    paste 接受两个类似文件的输入并创建一个两列单输出:

    paste <(printf "%s\n" "${array_1[@]}") <(printf "%s\n" "${array_2[@]}") 
    4   4
    4   1
    3   3
    

    一旦您将数组并排放置或者好像两个文件一样,然后将两者与awk diff comm perlruby 进行比较是微不足道的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-05
      • 2018-04-15
      • 2021-12-03
      • 2019-07-03
      • 1970-01-01
      • 2015-01-12
      • 2012-02-02
      • 1970-01-01
      相关资源
      最近更新 更多