使用awk打印一列并添加逗号。

18

我有一个文件,想要获取第一列,并在每个值之间添加逗号。

例如:

AAAA 12345 xccvbn
BBBB 43431 fkodks
CCCC 51234 plafad

获得

AAAA,BBBB,CCCC

我决定使用awk,于是我这样做了。

awk '{ $1=$1","; print $1 }'
问题是:这会在最后一个值上加上逗号,而这不是我想要的,同时每个值之间还有空格。 我该如何去除最后一个元素上的逗号,并消除空格呢?已经在手册中寻找了20分钟但没有成功。

3
你可能会发现这个有用:https://dev59.com/AWoy5IYBdhLWcg3wMLOj - jbub
不需要使用awk添加逗号,然后再将其传输到sed中去除逗号,这种方法很荒谬。只需不要添加逗号即可。 - Ed Morton
可能是重复的问题:Bash将多行字符串转换为单个逗号分隔符 - kvantour
如果有人发现这个有用的话,可能与此相关:如果你设置了-F,来让你的输入字段分隔符为逗号(或其他你喜欢的任何字符),那么BEGIN{OFS=FS}块将会把输出字段分隔符设为相同的。 - Marcel Besixdouze
11个回答

23
$ awk '{printf "%s%s",sep,$1; sep=","} END{print ""}' file
AAAA,BBBB,CCCC

或者如果你喜欢的话:

$ awk '{printf "%s%s",(NR>1?",":""),$1} END{print ""}' file
AAAA,BBBB,CCCC

或者如果你喜欢高尔夫,且对于大文件效率不介意:

$ awk '{r=r s $1;s=","} END{print r}' file
AAAA,BBBB,CCCC

2
哇,这非常明显:在第一个printf之后定义sep会使其第一次不出现。 - fedorqui
一些高尔夫的 awk '{printf (NR>1?",":"")"%s",$1} END{print ""}' - Jotne
3
如果你想打高尔夫球,那么 awk '{a=a s$1;s=","} END{print a}',但在我看来,这种方法对于大文件来说效率越来越低,并且越来越不清晰。 - Ed Morton

17
awk {'print $1","$2","$3'} file_name

这是我所知道的最短的。


完美。简单而短小。 - Arif
这里,OP想要从不同行获取$1。另外,逗号两侧会有一个空格。 - Kaushik

3
为什么要把它搞得那么复杂呢 :) (只要文件不太大)
awk '{a=NR==1?$1:a","$1} END {print a}' file
AAAA,BBBB,CCCC

为了更好的可移植性。
awk '{a=(NR>1?a",":"")$1} END {print a}' file

1
回答你的问题:这样做可能没问题,但对于大文件来说,由于字符串连接操作较慢且要构建的字符串较大,这种方式会明显变慢。此外,你在指定$1时有些冗余,并且非括号化的三元运算符可能会在某些awk中失败。 - Ed Morton
@EdMorton 同意,但是OP没有提到文件大小。 - Jotne
1
因此,“可能没问题”。顺便说一下,'{a=a (NR>1?",":"") $1} END {print a}' 可以解决冗余和可移植性问题。 - Ed Morton
@EdMorton 我确实看到我可以从测试中取出$1,但是那样我需要括号(本来就应该使用),并且需要添加 "" 使其更长。 - Jotne

2
在这种情况下,可以采用简单的复制和粘贴解决方案。
cut -d" " -f1 file | paste -s -d,

谢谢,这听起来很简单。虽然它没有使用查询中提到的 awk - susenj

2
awk 'NR==1{printf "%s",$1;next;}{printf "%s%s",",",$1;}' input.txt

它的意思是:如果是第一行,只打印第一个字段,对于其他行,先打印,,然后再打印第一个字段。

输出:

AAAA,BBBB,CCCC

1
+1:虽然 awk '{printf "%s",(NR==1?$1:","$1)}END{print ""}' file 可能更合适。 - jaypal singh
这不会在末尾添加新行。我没有看到 OP 有关此事的任何说明。 - Jotne

2
你可以这样做:
awk 'a++{printf ","}{printf "%s", $1}' file

a++被解释为一个条件语句。在第一行中,它的值为0,因此逗号不会被添加。

编辑: 如果您想要换行,您需要添加END{printf "\n"}。如果您在读取文件时遇到问题,也可以尝试:

cat file | awk 'a++{printf ","}{printf "%s", $1}'

考虑 aNR 之间的区别。添加换行符是 print ""。为什么读取文件会出现问题? - Ed Morton
我不明白你在第一句话中的意思?但也许使用NR作为条件会更优雅。感谢换行提示。 - Nils-o-mat
没错,因为NR已经提供了,所以你不需要一个单独的变量来计算记录数。 - Ed Morton

1
使用OFS(输出字段分隔符)的人似乎很少,以下是可能最简单的解决方案,仍然使用awk并在Linux和Mac上运行:使用“-v OFS =,”以逗号作为分隔符输出:

$ echo'1:2:3:4'| awk -F:-v OFS =,'{print $ 1,$ 2,$ 4,$ 3}'生成: 1,2,4,3

它也适用于多个字符: $ echo'1:2:3:4'| awk -F:-v OFS =。'{print $ 1,$ 2,$ 4,$ 3}'输出: 1.,2.,4.,3


1

如果有人像我一样想使用awk来清理docker镜像:

docker image ls | grep tag_name | awk '{print $1":"$2}'

0
这可以非常简单,像这样: awk -F',' '{print $1","$1","$2","$3}' inputFile

其中输入文件是:1,2,3 2,3,4 等。

0

使用 Perl

$ cat group_col.txt
AAAA 12345 xccvbn
BBBB 43431 fkodks
CCCC 51234 plafad

$ perl -lane ' push(@x,$F[0]); END { print join(",",@x) } ' group_col.txt
AAAA,BBBB,CCCC

$

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接