Bash - 打印出与参数匹配的行

时间:2014-03-23 17:35:04

标签: bash shell awk

我有一个看起来像这样的文件

3 5 4 0
0 0 0 0 
1 3 0 2

我想要的是我的bash脚本只打印不是全零的行。所以打印出来

3 5 4 0
1 3 0 2 

这就是我所拥有的,它运行时没有任何错误,但不会打印任何内容

    #!/bin/bash
    awk '{total=0; for(i=1;i<NR;i++)$i+=total
    if (total!=0) {for(i=1;i<NR;i++) printf("%d ", $i)}}total=0'

5 个答案:

答案 0 :(得分:3)

您的脚本没有打印任何内容,因为total=0是一个结果为零的赋值,这是一个错误的条件。看起来你又回到了让NR与NF混淆的地方。

无论如何,做你现在想做的事只是:

$ grep '[^0 ]' file
3 5 4 0
1 3 0 2

答案 1 :(得分:2)

你可以使用这个egrep:

egrep -v "^(\<0\> *)+$" file
3 5 4 0
1 3 0 2

使用awk:

awk '{k=0; for(i=1; i<=NF; i++) if ($i>0) {k=1;break}} k' file
3 5 4 0
1 3 0 2

答案 2 :(得分:2)

使用awk,你可以做到:

awk '{s=0;for(i=1;i<=NF;i++)if($i!=0)s=1}s' file 

或者以更易读的格式:

#!/usr/bin/awk -f
{
    s = 0 # flag is initialized to zero
    for (i = 1; i <= NF; i++) # For all fields
        if ($i != 0) # If we find a field that is not zero
            s = 1    # then set the flag to 1
}
s # Prints the current line (default action) if the flag is 
  # not zero (and not an empty string)

答案 3 :(得分:2)

一些简短awk

awk 'NF!=gsub(/0/,"&")' file
3 5 4 0
1 3 0 2

另一个,甚至更短:

awk -F"[0 ]*" 'NF>2' file
3 5 4 0
1 3 0 2

只是为了好玩,一些额外的:

awk '{a=$0;gsub(/ /,"")} $0+0 {print a}' file
3 5 4 0
1 3 0 2

正则表达式Ed使用:

awk '/[^0 ]/' file
3 5 4 0
1 3 0 2

获胜者是anubhava

我使用大文件测试了不同的解决方案,并且花费了多长时间。这是结果:

2.071s          awk '{k=0; for(i=1; i<=NF; i++) if ($i>0) {k=1;break}} k' large.txt >output
4.284s          awk 'NF!=gsub(/0/,"&")' large.txt >output
4.645s          awk '{a=$0;gsub(/ /,"")} $0+0 {print a}'  large.txt  >output
5.103s          awk 'NF!=gsub(/0/,"&")' large.txt >output
6.954s          grep '[^0 ]' large.txt >output
7.368s          awk '/[^0 ]/' large.txt  >output
9.374s          awk '{s=0;for(i=1;i<=NF;i++)if($i!=0)s=1}s' large.txt >output
12.007s         perl -lne '$s=0;map{$s+=$_}$_=~/([0-9]+)/g;print $_ if $s>0;' large.txt >output
25.575s         awk  -F"[0 ]*" 'NF>2' large.txt >output

答案 4 :(得分:0)

由于awk和其他建议已经发布,以下是使用perl进行此操作的方式:

$ perl -lne '$s=0;map{$s+=$_}$_=~/([0-9]+)/g;print $_ if $s>0;' file
3 5 4 0
1 3 0 2