2014-02-26 45 views
0

我有两个2D阵列文件可以用bash来读取。如何用bash比较两个二维数组文件?

我想要做的是提取这两个文件中的元素。

这两个文件包含不同行×列如:

FILE1.TXT(NX7)

NO DESC ID TYPE W S GRADE 
1 AAA 20 AD 100 100 E2 
2 BBB C0 U 200 200 D 
3 CCC 9G R 135 135 U1 
4 DDD 9H Z 246 246 T1 
5 EEE 9J R 789 789 U1 
. 
. 
. 

FILE2.TXT(MX3)

DESC W S 
AAA 100 100 
CCC 135 135 
EEE 789 789 
. 
. 
. 

这里是我想要做的:

  1. 提取DESC列中的元素file2.txt然后在file1.txt中找到对应的元素。

  2. 提取W,S等元素行中FILE2.TXT的则找到对应的W,FILE1.TXT的这样的行S中的元素。

  3. 如果[W1==W2 && S1==S2];然后echo "${DESC[colindex]} ok";其他echo "${DESC[colindex]} NG"

我怎么能看这种类型的文件作为一个二维数组bash或有任何方便的方式来做到这一点?

+0

替换列在'join'看看命令。 – chepner

+0

等待@肯特的回答,他肯定会发布最大。 30个字符长的awk脚本;) – jm666

回答

0

的bash不支持二维数组。您可以通过生成一维数组变量来模拟它们,如array1,array2等。

假设DESC是一个键(即,具有没有重复的值),并且不包含任何空格:

#!/bin/bash 

# read data from file1 
idx=0 
while read -a data$idx; do 
    let idx++ 
done <file1.txt 

# process data from file2 
while read desc w2 s2; do 
    for ((i=0; i<idx; i++)); do 
     v="data$i[1]" 
     [ "$desc" = "${!v}" ] && { 
      w1="data$i[4]" 
      s1="data$i[5]" 
      if [ "$w2" = "${!w1}" -a "$s2" = "${!s1}" ]; then 
       echo "$desc ok" 
      else 
       echo "$desc NG" 
      fi 
      break 
     } 
    done 
done <file2.txt 

为了简便起见,优化,例如利用排序顺序的被排除在外。

如果文件实际上包含标题NO DESC ID TYPE ...,则在处理之前使用tail -n +2将其丢弃。

更好的解决方案也是可能的,这避免在读取在存储器中的整个文件。这应该只与真正的大文件相关。

+0

谢谢!现在我知道如何用bash模拟二维数组,这对我非常有用! – liltme

0

如果不需要该行的次序被保留(可以排序),也许这就够了:

join -2 2 -o 1.1,1.2,1.3,2.5,2.6 <(tail -n +2 file2.txt|sort) <(tail -n +2 file1.txt|sort) |\ 
    sed 's/^\([^ ]*\) \([^ ]*\) \([^ ]*\) \2 \3/\1 OK/' |\ 
    sed '/ OK$/!s/\([^ ]*\) .*/\1 NG/' 

对于FILE1.TXT

NO DESC ID TYPE W S GRADE 
1 AAA 20 AD 100 100 E2 
2 BBB C0 U 200 200 D 
3 CCC 9G R 135 135 U1 
4 DDD 9H Z 246 246 T1 
5 EEE 9J R 789 789 U1 

和文件2。TXT

DESC W S 
AAA 000 100 
CCC 135 135 
EEE 789 000 
FCK xxx 135 

生产:

AAA NG 
CCC OK 
EEE NG 

说明:

  • 跳过标题行中两个文件 - 从两个文件tail +2
  • sort两个文件
  • join的需要的列成一张桌子,在结果将仅出现什么有共同DESC场

像旁边的线路:

AAA 000 100 100 100 
CCC 135 135 135 135 
EEE 789 000 789 789 
    的线,在2-4和3-5列中的值相同
  • ,每替代1,但与列OK
  • 在剩余行
  • NG
+0

至少在GNU尾巴中,指定'+ 2'需要在它之前使用'-n',如'tail -n + 2'。否则,“+2”被解释为文件名。 –

+0

@SirAthos谢谢 - 很高兴知道。我使用OS X - 所以bsd ... – jm666

+0

感谢您的解释,这对我也有帮助 – liltme