shell 中遍历文件的效果比较

假设我们有一个数据文件形如下:

A,B

A,C

A,D

B,E

B,F

D,A

D,B

E,G

....

 

需求是要将其转变为如下形式:

A:B,C,D

B:E,F

D:A,B

E,G

......

 

 

需求很简单,循环遍历文件,然后trace第一列即可。

在这里,我们讨论用Shell脚本如何实现这个简单的需求。

 

 

在shell中面对这样的需求,最好的办法莫过于使用awk了,不过除了awk之外,linux也有其他命令能遍历文件内容,比如说cat以及输入重定向等,下面我们就对这几种文件遍历方法做下比较。

 

首先申明一点,关于文件遍历过程中,如果得到目标结果的逻辑是一样的,说白了就是每读入一行,检查第一列而已。

 

1. awk方法:

 

BEGIN{
    FS=","
    curmember="";
}
{
    if(curmember==""){
        curmember=$1;
        offer=$2;
    }
    else if(curmember != $1){
        print curmember":"offer
        curmember=$1;
        offer=$2;
    }
    else{
        offer=offer","$2;
    }
}
END{
    print curmember":"offer;
}

 

 

2. forIn+cat方法:

 

#!/bin/bash
curmember="";
offer="";
#cat orderinfo | while read line
for line in `cat orderinfo`
do
    tmpmember=${line%%,*};
    if [  "$curmember" == ""  ]; then
        curmember=$tmpmember
        offer=${line##*,}
    elif [ "$tmpmember" != "$curmember" ]; then
        echo ${curmember}:${offer}
        curmember=${tmpmember}
        offer=${line##*,}
    else
        offer=${offer},${line##*,}
    fi
done
echo ${curmember}:${offer}

 

 

3. 文件描述符打开文件

 

#!/bin/bash
curmember="";
offer="";
exec 4<orderinfo
while read line<&4
do
    tmpmember=${line%%,*};
    if [  "$curmember" == ""  ]; then
        curmember=$tmpmember
        offer=${line##*,}
    elif [ "$tmpmember" != "$curmember" ]; then
        echo ${curmember}:${offer}
        curmember=${tmpmember}
        offer=${line##*,}
    else
        offer=${offer},${line##*,}
    fi
done
exec 4<&-
echo ${curmember}:${offer}

 

 

4. while循环中直接输入重定向

 

#!/bin/bash
curmember="";
offer="";
while read line
do
    tmpmember=${line%%,*};
    if [  "$curmember" == ""  ]; then
        curmember=$tmpmember
        offer=${line##*,}
    elif [ "$tmpmember" != "$curmember" ]; then
        echo ${curmember}:${offer}
        curmember=${tmpmember}
        offer=${line##*,}
    else
        offer=${offer},${line##*,}
    fi
done<orderinfo
echo ${curmember}:${offer}

 

 

四种方法的执行效率如下,文件行数69000+

 

 

awk   : 185 ms

forIn : 7187 ms

exec  : 7931 ms

while : 7708 ms

 

上述结果中awk速度是最快的,其他三个虽然各有快慢,但都差不多,而且都比awk要慢很多。

 

这也印证了awk在流式处理文件中的先天优势,同时其代码也是最简单的,屏蔽了文件操作的相关内容。

你可能感兴趣的:(shell)