Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash-打印出与参数匹配的行_Bash_Shell_Awk - Fatal编程技术网

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

Bash-打印出与参数匹配的行,bash,shell,awk,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' #/

我有一个像这样的文件

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'
#/bin/bash

awk'{total=0;对于(i=1;i您可以使用此egrep:

egrep -v "^(\<0\> *)+$" file
3 5 4 0
1 3 0 2
egrep-v“^(\*)+$”文件
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
awk'{k=0;for(i=1;i0){k=1;break}k'文件
3 5 4 0
1 3 0 2
使用awk,您可以执行以下操作:

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

awk'{s=0;for(i=1;i您的脚本没有打印任何内容,因为
total=0
是一个结果为零的赋值,这是一个错误的条件。看起来您又将NR与NF混淆了

不管怎样,做你现在说的你想做的只是:

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

既然已经发布了
awk
和其他建议,下面是使用
perl
的方法:

$ perl -lne '$s=0;map{$s+=$_}$_=~/([0-9]+)/g;print $_ if $s>0;' file
3 5 4 0
1 3 0 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
regex 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
2.071s awk'{k=0;for(i=1;i0){k=1;break}}k'large.txt>输出
4.284s awk'NF!=gsub(/0/,“&”)'large.txt>输出
4.645s awk'{a=$0;gsub(/,“”)}$0+0{print a}'large.txt>输出
5.103s awk'NF!=gsub(/0/,“&”)'large.txt>输出
6.954s grep“[^0]”large.txt>输出
7.368s awk'/[^0]/'large.txt>输出
9.374s awk'{s=0;for(i=1;i0;'large.txt>输出
25.575s awk-F“[0]*”'NF>2'large.txt>输出

问题是,我希望bash脚本来完成这项工作。我只想./script<文件,然后打印出我想要的内容。我为您提供了grep和awk解决方案。正如JayPal在我的帖子中指出的那样,
egrep
会对像这样的
10 20 30 40
这样的行给出假阳性结果使用
\
中的单词边界,您可以自己尝试。@Tree55Topz添加了一个解释。如果有什么您不喜欢的,请告诉我:
perl-MList::MoreUtils=all-lane'打印,除非所有{$\u==0}@F'
获胜者是
anubhava
,有两个最快的解决方案:)如果行中包含类似于
10203040
的内容,则第一个解决方案将中断。即,4个字段,虽然它们不包含所有零,但足以中断条件。@jaypal我现在在测试它时看到了这一点。删除了anubhavas
egrep
解决方案。
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