使用bash更改一系列列的列delims

时间:2017-10-02 18:56:17

标签: awk sed

我有一个包含多列的表格,我想跳过第一列和第二列。然后我想将(n + 2列)的分隔符从制表符更改为逗号。任何使用awk或sed的建议都是有用的,因为通常我只能找到并替换(使用sed),但我会继续替换前两列中的选项卡。

示例测试集:

M1  D.130   a   a   a
M2  D.104   -   a   ab
M3  D.150   ab  ab  a
M4  D.160   a   a   -
M5  D.107   a   ab  a
M6  D.107   -   ab  -
M7  D.104   a   ab  ab

期望的输出:

M1  D.130   a,a,a
M2  D.104   -,a,ab
M3  D.150   ab,ab,a
M4  D.160   a,a,-
M5  D.107   a,ab,a
M6  D.107   -,ab,-
M7  D.104   a,ab,ab

5 个答案:

答案 0 :(得分:3)

对于给定的输入,您只需使用下面的

即可
awk '{print $1, $2, $3 "," $4 "," $5}' infile

否则

awk -v n=3 '{for(i=1; i<=NF; i++)printf("%s%s",$i,i==NF?ORS:i<n?OFS:",")}' infile

gawk保留原始间距:

awk -v n=3 '{
              split($0,t,FS,d);
              for(i=1; i<=NF; i++)
                printf("%s%s",$i,i==NF?ORS:i<n?d[i]:",")
            }' infile

非保持原始间距:

awk -v n=3 '{
              split($0,d,/[^[:space:]]*/);
              for(i=1; i<=NF; i++)
                 printf("%s%s",$i,i==NF?ORS:i<n?d[i+1]:",")
            }' infile

例如:

$ cat infile
M1  D.130   a   a   a
M2  D.104   -   a   ab
M3  D.150   ab  ab  a
M4  D.160   a   a   -
M5  D.107   a   ab  a
M6  D.107   -   ab  -
M7  D.104   a   ab  ab

$ awk -v n=3 '{for(i=1; i<=NF; i++)printf("%s%s",$i,i==NF?ORS:i<n?OFS:",")}' file
M1 D.130 a,a,a
M2 D.104 -,a,ab
M3 D.150 ab,ab,a
M4 D.160 a,a,-
M5 D.107 a,ab,a
M6 D.107 -,ab,-
M7 D.104 a,ab,ab

Gawk保留原始间距

$ awk -v n=3 '{split($0,t,FS,d);for(i=1; i<=NF; i++)printf("%s%s",$i,i==NF?ORS:i<n?d[i]:",")}' infile
M1  D.130   a,a,a
M2  D.104   -,a,ab
M3  D.150   ab,ab,a
M4  D.160   a,a,-
M5  D.107   a,ab,a
M6  D.107   -,ab,-
M7  D.104   a,ab,ab

non-Gawk保留原始间距

$ awk -v n=3 '{split($0,d,/[^[:space:]]*/);for(i=1; i<=NF; i++)printf("%s%s",$i,i==NF?ORS:i<n?d[i+1]:",")}' infile
M1  D.130   a,a,a
M2  D.104   -,a,ab
M3  D.150   ab,ab,a
M4  D.160   a,a,-
M5  D.107   a,ab,a
M6  D.107   -,ab,-
M7  D.104   a,ab,ab

答案 1 :(得分:1)

使用GNU awk为第3个arg匹配():

$ awk 'match($0,/(([^\t]+\t){2})(.*)/,a) {gsub(/\t/,",",a[3]); print a[1] a[3]}' file
M1      D.130   a,a,a
M2      D.104   -,a,ab
M3      D.150   ab,ab,a
M4      D.160   a,a,-
M5      D.107   a,ab,a
M6      D.107   -,ab,-
M7      D.104   a,ab,ab

任何awk:

$ awk 'match($0,/([^\t]+\t){2}/) {r=substr($0,RLENGTH+1); gsub(/\t/,",",r); print substr($0,1,RLENGTH) r}' file
M1      D.130    a,a,a
M2      D.104    -,a,ab
M3      D.150    ab,ab,a
M4      D.160    a,a,-
M5      D.107    a,ab,a
M6      D.107    -,ab,-
M7      D.104    a,ab,ab

答案 2 :(得分:0)

您可以使用此awk命令:

$ awk '{for(i=3; i<NF; i++){a=a$i","} {OFS="  "; print $1,$2,a$NF} a=""}' file
M1  D.130  a,a,a
M2  D.104  -,a,ab
M3  D.150  ab,ab,a
M4  D.160  a,a,-
M5  D.107  a,ab,a
M6  D.107  -,ab,-
M7  D.104  a,ab,ab

答案 3 :(得分:0)

简单 awk 方法:

awk -F'\t' '{ r=$1 FS $2 FS $3; for(i=4;i<=NF;i++) r=r","$i; print r }' file

输出:

M1  D.130   a,a,a
M2  D.104   -,a,ab
M3  D.150   ab,ab,a
M4  D.160   a,a,-
M5  D.107   a,ab,a
M6  D.107   -,ab,-
M7  D.104   a,ab,ab

答案 4 :(得分:0)

使用sed

sed 's/\t/,/3;s/\t/,/3' file