2

我有一个unix问题。我有一个看起来像这样的文件:

AAAA    0   1   2   2   0

BBBBB   2   2   2   2   2

CCCCC   1   1   0   1   1

DDDD    0   0   0   0   0

EEEEE   2   2   0   2   2

该文件有数千行这样的(并且也是制表符分隔的)。文件的第一列是名称,第 2 到第 6 列是数据。重要的是第 2-6 列中的信息。我需要输出第 2-6 列不超过 1 0(零)的所有行。例如,我希望输出如下所示:

BBBBB   2   2   2   2   2

CCCCC   1   1   0   1   1

EEEEE   2   2   0   2   2

我一直在尝试以尽可能简单的方法执行此操作,并尝试了以下 awk 命令:

awk 'BEGIN{out!=0;}{if($2!=0)out++;if($3!=0)out++;if($4!=0)out++;if($5!=0)out++;if($6!=0)out++;if (out>=4)print;}'

但是,当我尝试这个时,它只是给了我原始输入文件。我不确定出了什么问题,或者我是否采取了正确的方法。任何帮助,将不胜感激。

4

5 回答 5

2

您正在做的错误不是为每条记录重置 out 变量,而是在 BEGIN 块中只初始化一次。(您也错误地使用“不等于”进行初始化。)

awk '{out = 0; if($2!=0) out++; if($3!=0) out++; if($4!=0) out++; if($5!=0) out++; if($6!=0) out++; if(out>=4) print}'
于 2012-06-21T00:04:24.117 回答
0

一种使用方式perl

perl -ne 'print if(tr/0/0/ <= 1)' file.txt

我假设每行上的名称不包含数字(特别是0),并且它们的长度不超过一位。此外,如果添加-i标志,则可以在文件中进行更改。

于 2012-06-21T00:36:26.003 回答
0

假设列符合特定格式可能很危险。以下是使用布尔变量的 0,1 属性的简单解决方案:

awk '($2==0) + ($3==0) + ($4==0) + ($5==0) + ($6==0) <2' file.txt
于 2012-06-22T14:37:32.923 回答
0

更简单的方法是:

awk '{count=0;for(i=2;i<=NF;i++){if($i~/0/)++count;}if(count <=1)print}' file1

测试如下:

> cat file1
AAAA    0       1       2       2       0
BBBBB   2       2       2       2       2
CCCCC   1       1       0       1       1
DDDD    0       0       0       0       0
EEEEE   2       2       0       2       2
sEEEE   2       0       0       0       2
> awk '{count=0;for(i=2;i<=NF;i++){if($i~/0/)++count;}if(count <=1)print}' file
BBBBB  2 2 2 2 2
CCCCC  1 1 0 1 1
EEEEE  2 2 0 2 2
> 
于 2012-06-21T05:20:06.793 回答
0
awk '
  {
    nzero=0
    for (fld = 2; nzero <= 1 && fld <= 6; fld++) {
      if ($fld == 0) nzero++
    }
    if (nzero <= 1) print
  }
' filename
于 2012-06-21T01:05:35.070 回答