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我现在在测试它时看到了这一点。删除了anubhavasegrep
解决方案。
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