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

使用awk打印文本文件的第1列和第n列,awk,Awk,我有一个txt文件,共包含10177列和大约450000行。信息由选项卡分隔。我正在尝试使用awk对文件进行裁剪,以便只打印第1-3列、第5列和第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

我有一个txt文件,共包含10177列和大约450000行。信息由选项卡分隔。我正在尝试使用awk对文件进行裁剪,以便只打印第1-3列、第5列和第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来使用该代码):

当用excel程序打开时,结果都被压缩成一个单元格

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

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

for(i=0;iAwk字段编号、字符串和数组索引都从1开始,而不是从0开始,因此当您这样做时:

for (i=0;i<=3;i++) printf "%s ",$i 
但永远不要将输入数据作为printf的唯一参数来执行printf,因为printf会将其视为一个没有数据的格式字符串(而不是您想要的,它是一个包含数据的纯字符串格式)然后,如果输入数据包含格式化字符,如
%s
%d
,则该操作将以加密方式失败。因此,请始终使用
printf“%s”、$i
,而不要使用
printf$i

我猜,你在使用excel时遇到的问题是,你试图双击该文件,并希望excel知道如何处理它(它不会这样做,不像这是CSV)。但是,你可以在打开excel后将选项卡分隔的文件导入到excel中-谷歌就是这样

你想要的是:

123518...ABCER...XYXXY...
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
awk'
开始{FS=OFS=“\t”}
{
对于(i=1;i1?OFS:),$i
}

对于(i=5;iAwk字段编号、字符串和数组索引都从1开始,而不是从0开始,因此当您这样做时:

for (i=0;i<=3;i++) printf "%s ",$i 
但永远不要将输入数据作为printf的唯一参数来执行printf,因为printf会将其视为一个没有数据的格式字符串(而不是您想要的,它是一个包含数据的纯字符串格式)然后,如果输入数据包含格式化字符,如
%s
%d
,则该操作将以加密方式失败。因此,请始终使用
printf“%s”、$i
,而不要使用
printf$i

我猜,你在使用excel时遇到的问题是,你试图双击该文件,并希望excel知道如何处理它(它不会这样做,不像这是CSV)。但是,你可以在打开excel后将选项卡分隔的文件导入到excel中-谷歌就是这样

你想要的是:

123518...ABCER...XYXXY...
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
awk'
开始{FS=OFS=“\t”}
{
对于(i=1;i1?OFS:),$i
}

对于(i=5;i我会尝试按照下面的思路来解决这个问题

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

我很想按照下面的思路来解决这个问题,我想你会发现不用awk迭代可以节省时间

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

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

$ 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
$awk'开始{FS=OFS=“\t”}
{

对于awk中的(i=1;i,在
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
$awk'开始{FS=OFS=“\t”}
{
对于(i=1;i