2016-12-13 58 views
0

我想打印下列文件,其中前六列总是由制表符分隔,其余(可以是两个或更多)始终以空格分隔。使用两种字段分隔符awk打印列

对于一个样本文件:

1 1 0 0 1 0 2 2 1 1 
1 2 0 0 2 0 2 2 1 1 
1 3 1 2 1 0 2 2 1 1 
1 4 1 2 2 0 2 2 1 1 
1 5 1 2 1 0 2 2 1 1 
1 6 1 2 1 0 2 2 1 1 
1 7 1 2 2 0 2 2 1 1 

我通过键入做到这一点:

awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7" "$8" "$9" "$10}' file 

但不是从开始第7栏打字,我想说的列的其余部分的数的列不尽相同。

谢谢!

回答

0

您可以使用for遍历字段。

{ 
    for (i=1; i<=NF; i++) { 
     if (i<7) { 
      ORS="\t" 
     } else if (i != NF) { 
      ORS=" " 
     } else { 
      ORS="\n" 
     } 
     print $i 
    } 
} 

$ awk -f prog.awk file 
1 1 0 0 1 0 2 2 1 1 
1 2 0 0 2 0 2 2 1 1 
1 3 1 2 1 0 2 2 1 1 
1 4 1 2 2 0 2 2 1 1 
1 5 1 2 1 0 2 2 1 1 
1 6 1 2 1 0 2 2 1 1 
1 7 1 2 2 0 2 2 1 1 
0
{ 
    r = $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t"; 
    for (i=7; i<=NF; i++) { 
     r = r $i " "; 
    } 
    print substr(r,1,length(r)-1) 
} 

您的代码工程领域的静态数量。

NF变量包含当前记录的字段总数。 所以你可以在for循环中使用它来动态连接字段。

此外,循环结尾还有一个剩余空间,由substr删除。

+0

虽然此代码片段可能会解决问题,但[包括解释](// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高帖子的质量。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性注释来挤占代码,这会降低代码和解释的可读性! – kayess

0

这是如何真正做到这一点:

$ awk '{$1=$1; for(i=1;i<=6;i++) sub(/ /,"\t")}1' file 
1  1  0  0  1  0  2 2 1 1 
1  2  0  0  2  0  2 2 1 1 
1  3  1  2  1  0  2 2 1 1 
1  4  1  2  2  0  2 2 1 1 
1  5  1  2  1  0  2 2 1 1 
1  6  1  2  1  0  2 2 1 1 
1  7  1  2  2  0  2 2 1 1 

$1=$1重新编译当前记录替换的连续空白(FS)使用单个空格字符(OFS)所有序列中,sub()只是替换了第一个空白在一个标签的行上,并且该循环重复6次,即sub()

0

与GNU sed

$ sed -r 's/ +/\t/g; s/\t/ /7g' file 

1  1  0  0  1  0  2 2 1 1 
1  2  0  0  2  0  2 2 1 1 
1  3  1  2  1  0  2 2 1 1 
1  4  1  2  2  0  2 2 1 1 
1  5  1  2  1  0  2 2 1 1 
1  6  1  2  1  0  2 2 1 1 
1  7  1  2  2  0  2 2 1 1 

第一转换字段分隔符选项卡,然后从空间到7日结束更改。如果这些字段已经制表符分隔,则可以跳过第一条语句。