两个文件,从文件b首列查找出等于文件a的行并输出
[root@localhost ~]# cat a
1
3
6
7
[root@localhost ~]# cat b
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9

shell脚本
[root@localhost ~]# cat jieguo
#!/bin/bash
y=`sed -n 'p' a |wc -l`  #a 行数
x=`sed -n 'p' b |wc -l`  #b行数
for((i=1;i<=$y;i++))
do
   value_a=`sed -n ${i}p a`   #按行输出,赋值给a
  for((j=1;j<=$x;j++))
  do
    value_b=`awk '{print $1}' b|sed -n "/$j/p"`  #输出首列,赋值给b
 if [ "$value_a" = "$value_b" ]        #判断value_a,value_b是否相等
        then
          value_c=`sed -n ${j}p b`
          echo $value_c >> /root/value_c   #相等输出b中的行到value_c  
      fi
 done
done

awk命令行
awk 'NR==FNR{k[$1]=$1} NR>FNR{ if(k[$1]==$1) {print $1,$2,$3}}' a b 或
awk 'NR==FNR{k[$1]=$1} NR>FNR{ if(k[$1]==$1) {print $0}}' a b
NR:awk处理文件的总行数
FNR:awk处理当前文件的行数
数组k[$1]:将文件a的值付给数组k。

条件语句:NR==FNR 对文件a执行{}中的操作
                    NR>FNR  对文件b执行{}中的操作
                    k[$1]=$1中的$1是文件a中的第一个域
                    if(k[$1]==$1) {print $1,$2,$3}是文件b中的1,2,3个域
                    $0是当前的一条完整的记录

区别:

脚本:需要嵌套for来遍历整个文件,就是说我要比较a与b的首行是否相同的,需要a中每个数字循环遍历b中首行的数据。需要x*y次比较。

awk:数组k[$1]可以理解成将文件a的值由列变换成行,这样在awk做if判断时,是在一行数据中查找目标,而不需要像列一样需要for循环语句来遍历整个文件。就是从b的首行拿出数据与k数组作比较,数据相同,就输出。只需要比较x次。

运行结果:
[root@localhost ~]# ./jieguo
1 2 3
3 4 5
6 7 8
7 8 9
[root@localhost ~]# awk 'NR==FNR{k[$1]=$1} NR>FNR{ if(k[$1]==$1) {print $0}}' a b
1 2 3
3 4 5
6 7 8
7 8 9

如果文件的行数有几万,几十万行,脚本是很费时的。awk秒出结果。。。

2014-08-29补充:

awk命令中打印的是b中的内容,如果是输出两个文件中相同的部分,两个文件的前后位置无所谓;如果是输出不相同的,要把想输出内容所在的文件放在后面的位置。

例子:

[root@DT-CenterDB01 tmp]# awk 'NR==FNR{k[$1]=$1} NR>FNR{if (k[$1]!=$1) {print $0}}' a b
8
9
10
11
[root@DT-CenterDB01 tmp]# awk 'NR==FNR{k[$1]=$1} NR>FNR{if (k[$1]!=$1) {print $0}}' b a
1
2
3
4

[root@DT-CenterDB01 tmp]# awk 'NR==FNR{k[$1]=$1} NR>FNR{if (k[$1]==$1) {print $0}}' a b
5
6
7

[root@DT-CenterDB01 tmp]# cat a
1
2
3
4
5
6
7

[root@DT-CenterDB01 tmp]# cat b
5
6
7
8
9
10
11

a,b两个文件输出不相等的内容,ab的位置不同,输出结果也不同。