【问题标题】:How to Compare Two Arrays in Shell Script如何在 Shell 脚本中比较两个数组
【发布时间】:2021-03-28 08:17:20
【问题描述】:

我有两个 SQL 文件 A.sql 和 B.sql。我的要求是比较 A.s​​ql 和 B.sql,我需要检查 A.sql 中存在的查询是否存在于 B.sql 中,如果 B.sql 中不存在,那么我们需要打印内容它们在 A.sql 中有,而在 B.sql 中没有。所以基本上我将 SQL 查询存储到分号作为一个查询并比较两个数组并打印内容。

下面是例子

A.sql

Select * from emp;
Select * from dept;
Select * from student;
Select * from subject;

B.sql

Select * from emp;
Select * from dept;
Select * from student;

输出例外

Select * from subject;

输出我得到的东西

Select * from emp;

下面是我的脚本

 i=0
 while read -rd ';' first_sql
    do
      first_array[$i]=$first_sql
      i=$((i+1))
    done < A.sql 
  
 j=0
    while read -rd ';'second_sql
    do
      second_array[$j]=$second_sql
      j=$((j+1))
    done < B.sql 

for p in "${first_array[@]}"; do
  flag=false
  for q in "${second_array[@]}"; do
    if [[ $p == $q ]]; then
      echo "$p is in first_array"
      flag=true
      break
    fi
  done
  echo $flag 
echo "$p is not in first_array"
done

所以现在我正在读取第一个 SQL 文件,即 A.sql,直到分号作为一个查询并将其存储到数组中。

 i=0
    while read -rd ';' first_sql
    do
      first_array[$i]=$first_sql
      i=$((i+1))
    done < A.sql 

所以现在我正在读取第二个 SQL 文件,即 B.sql,直到分号作为一个查询并将其存储到数组中。

j=0
while read -rd ';'second_sql
do
  second_array[$j]=$second_sql
  j=$((j+1))
done < B.sql 

现在我正在比较 first_array 和 second_array 并打印存在于 first_array 中的内容,而不存在于内部 for 循环之外的 second_array 中。

for p in "${first_array[@]}"; do
  flag=false
  for q in "${second_array[@]}"; do
    if [[ $p == $q ]]; then
      echo "$p is in first_array"
      flag=true
      break
    fi
  done
  echo $flag 
echo "$p is not in first_array"
done

任何人都可以帮助解决上述问题并让我知道出了什么问题。

注意:我的一个 SQL 查询不占一行,会超过 4-5 行。仅举个例子,我使用了单行查询。

因为我的一个 SQL 查询有超过 4-5 行,所以我在 while 循环中读取 SQL 查询直到分号并将其存储在一个数组中,然后我比较这两个数组以打印不匹配的内容.

提前致谢!!!

【问题讨论】:

  • 为什么不能运行diff first_sql second_sql
  • 试过了,但没有按预期工作。由于我的 SQL Query 不是单行查询,所以会占用超过 4-5 行。为了解释这个问题,例如我在这里使用了单行查询。
  • “预期”是什么意思?如果查询在文件中的顺序不同,会发生什么?如果一个查询被另一个查询替换,会发生什么?
  • 例如。在 Sql 查询中,一切都是相同的,只有值不同,当我们执行 diff first_sql second_sql 时,我得到的只是不同的值,而不是整个查询
  • 删除 for p in "${first_array[@]}"; dofor q in .... 中的引号有帮助吗?我希望两个循环只运行一次。

标签: sql arrays bash shell unix


【解决方案1】:

您可以使用使用comm 的单行来仅打印出现在第一个文件中的语句,并通过一些预处理和后处理来解决多行 sql 语句:

$  comm -z -23 <(perl -0777 -pe 's/;\n/;\x{0}/g' a.sql | sort -z) \
               <(perl -0777 -pe 's/;\n/;\x{0}/g' b.sql | sort -z) \
   | tr "\0" "\n"
Select * from subject;

(这确实假设一个 GNU 用户空间;commsort 的其他版本可能不会采用 -z 选项)。

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2016-01-16
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多