Bash - 使用循环打印具有特定列的所有行

时间:2015-12-14 20:22:15

标签: bash awk

我已经坚持这个问题几个小时了,所以我决定向这个社区提问。

我有一个这样的日志文件:

gzz kre 1
mnt ttt 1
ddr ppp 2
ret typ 2
epo sst 1
plt ewr 3

我想将此文件分成三个不同的文件,每个文件在第三列中具有相同的值。

我可以使用awk:

静态地执行此操作
awk '$3 == 1'  dataTX.txt > dataTX_2_$i.txt

然而,我不能使用循环来做到这一点。我正在尝试这个:

for i in `seq 1 3`;
do
    awk '$3 == $i'  dataTX.txt > dataTX_2_$i.txt

done

但三个输出文件中没有任何内容。

任何人都可以帮助我吗?

非常感谢: - )

2 个答案:

答案 0 :(得分:4)

您可以使用单个awk中的所有内容:

awk '{print > ("dataTX_2_" $3 ".txt")}' dataTX.txt

答案 1 :(得分:1)

有一个更好的答案,请参阅@ anubhava&#39。

方法

你的方法(以及我原来的答案,下面)有几个问题:

  • 多次读取输入文件而不是一次
  • 对值进行硬编码,而不是从输入中动态拾取

@ anubhava的解决方案通过在单个awk进程中重定向输出,对输入进行单次传递,并动态获取用于输出文件名的值来处理这些问题。作为额外的奖励,没有必要的条件。

原始答案,乐队帮助错误的方法

您需要使用双引号来嵌入shell变量,然后在这种情况下转义\$中的$3,如下所示:

for i in `seq 1 3`;
do
    awk "\$3 == $i"  dataTX.txt > dataTX_2_$i.txt    
done

顺便说一下,如果可能,请避免seq。这也可以做到这一点,并且更加便携:

for i in {1..3};
do
    awk "\$3 == $i"  dataTX.txt > dataTX_2_$i.txt    
done

另一种选择是将值注入带有-v标志的Awk变量,而不是搞乱引用:

for i in {1..3};
do
    awk -v i=$i '$3 == i'  dataTX.txt > dataTX_2_$i.txt    
done