使用awk打印文本文件的第1列和第n列

时间:2016-12-08 02:34:39

标签: awk

我有一个txt文件,共包含10177列,总共约450,000行。信息由选项卡分隔。我正在尝试使用awk修剪文件,以便它只在第五列之后打印1-3,5和每14列。

我的文件格式如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 10177
A B C D E F G H I J  K  L  M  N  O  P  Q  R  S  T  ...
X Y X Y X Y X Y X Y  X  Y  X  Y  X  Y  X  Y  X  Y  ...

我希望生成一个输出txt文件(也用tab分隔),其中包含:

1 2 3 5 18 ...
A B C E R  ...
X Y X X Y  ...

我看起来的当前awk代码(我使用cygwin来使用代码):

$ awk -F"\t" '{OFS="\t"} { for(i=5;i<10177;i+=14) printf ($i) }' test2.txt > test3.txt

但我得到的结果显示如下:

123518...ABCER...XYXXY...

使用excel程序打开时,结果全部被分成1个单元格。

此外,当我尝试包含代码时

for (i=0;i<=3;i++) printf "%s ",$i 

在awk中获取前3列,它只是打印出原始输入文档和mashed结果。我不熟悉awk,所以我不确定是什么导致了这个问题。

3 个答案:

答案 0 :(得分:2)

Awk字段编号,字符串和数组索引都从1开始,而不是0,所以当你这样做时:

for (i=0;i<=3;i++) printf "%s ",$i 

第一次迭代打印$0,这是整个记录。

您通过以下方式走上正轨:

$ awk -F"\t" '{OFS="\t"} { for(i=5;i<10177;i+=14) printf ($i) }' test2.txt > test3.txt

但是从来没有使用输入数据作为printf的唯一参数printf,因为那时printf会把它当作没有数据的格式字符串(而不是你想要的那些是你的数据的普通字符串格式)然后这会以密码方式失败if /何时输入数据包含%s%d等格式字符。因此,请始终使用printf "%s", $i,而不是printf $i

我猜想,你在excel中遇到的问题是,你是否正试图双击该文件并希望excel知道如何处理它(它不会,不像是这是一个CSV)。您可以在打开标签分隔文件后将其导入excel - 谷歌即可。

你想要这样的东西:

awk '
    BEGIN { FS=OFS="\t" }
    {
        for (i=1; i<=3; i++) {
            printf "%s%s", (i>1?OFS:""), $i
        }
        for (i=5; i<=NF; i+=14) {
            printf "%s%s", OFS, $i
        }
        print ""
    }
' file

我强烈推荐Arnold Robbins撰写的Effective Awk Programming,第4版。

答案 1 :(得分:1)

在awk中使用for中的条件运算符:

$ awk 'BEGIN { FS=OFS="\t" }
       {
           for(i=1; i<=NF; i+=( i<3 ? 1 : ( i==3 ? 2 : 14 )))
               printf "%s%s", $i, ( (i+14)>NF ? ORS : OFS)
       }' file
1 2 3 5 19
A B C E S
X Y X X X

for if i<3增加1时,如果i==3增加2,则增加到5,之后增加到14。

答案 2 :(得分:0)

我很想通过以下方式解决问题。我想你会发现你不用在awk中迭代来节省时间。

$ cols="$( { echo 1 2 3; seq 5 14 10177; } | sed 's/^/$/; 2,$ s/^/, /' )"
$ awk -F\\t "{print $cols}" test.txt