简体   繁体   English

如何在 Shell 脚本中比较两个 Arrays

[英]How to Compare Two Arrays in Shell Script

I have two SQL files A.sql and B.sql.我有两个 SQL 文件 A.sql 和 B.sql。 My requirement is to compare A.sql and B.sql and I need to check query which are present in A.sql is present in B.sql or not, if it is not there in B.sql then we need to print the contents which are there in A.sql and not there in B.sql. My requirement is to compare A.sql and B.sql and I need to check query which are present in A.sql is present in B.sql or not, if it is not there in B.sql then we need to print the contents它们在 A.sql 中有,而在 B.sql 中没有。 So basically i am storing the SQL Query upto Semicolon as one query and comparing both the arrays and printing the content.所以基本上我将 SQL 查询存储到分号作为一个查询,并比较 arrays 和打印内容。

Below is the Example下面是示例

A.sql A.sql

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

B.sql B.sql

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

Output Excepted Output 除外

Select * from subject;

Output what I am getting Output 我得到了什么

Select * from emp;

Below is my script下面是我的脚本

 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

So now I am reading first SQL file ie A.sql upto Semicolon as a one query and storing it to the array.所以现在我正在阅读第一个 SQL 文件,即 A.sql 作为一个查询并将其存储到数组中。

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

So now I am reading Second SQL file ie B.sql upto Semicolon as a one query and storing it to the array.所以现在我正在阅读第二个 SQL 文件,即 B.sql 作为一个查询并将其存储到数组中。

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

Now I am comparing first_array and second_array and printing the contents which are present in first_array and not present in second_array outside the inner for loop.现在我正在比较 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

Can anyone please help with the above issue and let me know what is wrong.任何人都可以请帮助解决上述问题,并让我知道出了什么问题。

Note: My one SQL query doesn't occupies single line, it will be more than 4-5 lines.注意:我的一个 SQL 查询不占用单行,它将超过 4-5 行。 Just for an example I have used a single line query.仅举一个例子,我使用了单行查询。

Since my one SQL query is having more than 4-5 lines, so I am reading SQL query in while loop upto semicolon and storing it in a array and then i am comparing those two array to print the unmatched contents.由于我的一个 SQL 查询有超过 4-5 行,所以我在 while 循环中读取 SQL 查询,直到分号并将其存储在一个数组中,然后我比较这两个数组以打印不匹配的内容。

Thanks in advance!!!提前致谢!!!

You can do it with a one liner that uses comm to print out just the statements that appear in the first file, with a bit of pre and post processing to account for multi-line sql statements:您可以使用一个使用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;

(This does assume a GNU userland; other versions of comm and sort might not take the -z option). (这确实假设一个 GNU 用户空间;其他版本的commsort可能不采用-z选项)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM