简体   繁体   English

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

[英]Bash - Print all rows with a specific column using loops

I've stucked on this problem for few hours, so I decided to ask to this community. 我已经坚持这个问题几个小时,所以我决定问这个社区。

I have a log file like this: 我有一个这样的日志文件:

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

I want to divide this file in three different files, each one having the same value in the third column. 我想将这个文件分成三个不同的文件,每个文件在第三列中具有相同的值。

I am able to do this statically, using awk: 我可以使用awk静态地执行此操作:

awk '$3 == 1'  dataTX.txt > dataTX_2_$i.txt

Nevertheless, I can't do this using a loop. 不过,我不能用循环来做到这一点。 I'm trying with this: 我正在尝试这个:

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

done

But nothing appears in the three output files. 但三个输出文件中没有任何内容。

Can anyone help me? 谁能帮我?

Thanks a lot :-) 非常感谢 :-)

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

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

There is a better answer, see @anubhava's. 有一个更好的答案,请参阅@ anubhava's。

Approach 途径

Your approach (and my original answer, below) have several problems: 你的方法(以及我原来的答案,下面)有几个问题:

  • Reading the input file several times instead of once 多次读取输入文件而不是一次
  • Hardcoding of the values instead of picking up dynamically from the input 硬编码值而不是从输入动态拾取

@anubhava's solution takes care of these, by redirecting the output inside a single awk process, making a single pass over the input, and dynamically picking up the values to use for the output filenames. @ anubhava的解决方案通过在单个awk进程中重定向输出,对输入进行单次传递,并动态获取用于输出文件名的值来处理这些问题。 As an added bonus, there are no more conditions necessary. 作为额外的奖励,没有必要的条件。

Original answer, band-aiding the wrong approach 原始答案,乐队帮助错误的方法

You need to use double-quotes to embed a shell variable, and then in that case escape the \\$ in $3 , like this: 你需要使用双引号来嵌入一个shell变量,然后在这种情况下转义\\$ in $3 ,如下所示:

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

Btw, avoid seq if possible. 顺便说一句,如果可能的话,避免使用seq This will do the job just as well, and more portable: 这也可以做到这一点,并且更加便携:

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

Instead of messing with the quoting, another option is to inject a value into an Awk variable with the -v flag: 另一种选择是使用-v标志将值注入到Awk变量中,而不是搞乱引用:

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

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

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