首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux csv文件将列连接到一列中

linux csv文件将列连接到一列中
EN

Stack Overflow用户
提问于 2018-03-07 00:21:52
回答 6查看 1.9K关注 0票数 4

我一直在寻找使用sed、awk或cut来实现这一点。我愿意使用任何其他我可以通过管道传输数据的命令行程序。

我有一大组逗号分隔的数据。这些行有14到20列。我需要递归地将第10列与每行的第11列连接在一起,这样每一行都恰好有14列。换句话说,这就是:

代码语言:javascript
复制
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p

将成为:

代码语言:javascript
复制
a,b,c,d,e,f,g,h,i,jkl,m,n,o,p

我可以得到前10列。我可以得到最后N列。我可以连接多个列。我无法想象如何在一行中做到这一点,这样我就可以通过它传递一个无限的数据流,最后每行恰好有14列。

示例(根据请求):

这一行有多少列?

代码语言:javascript
复制
sed 's/[^,]//g' | wc -c

获取前10列:

代码语言:javascript
复制
cut -d, -f1-10

获取最后4列:

代码语言:javascript
复制
rev | cut -d, -f1-4 | rev

将第10列和第11列连接起来,然后显示第1-10列:

代码语言:javascript
复制
awk -F',' ' NF { print $1","$2","$3","$4","$5","$6","$7","$8","$9","$10$11}'
EN

回答 6

Stack Overflow用户

发布于 2018-03-07 00:47:15

Awk解决方案:

代码语言:javascript
复制
awk 'BEGIN{ FS=OFS="," }
     { 
         diff = NF - 14;
         for (i=1; i <= NF; i++)
             printf "%s%s", $i, (diff > 1 && i >= 10 && i < (10+diff)?
                                 "": (i == NF? ORS : ",")) 
     }' file

输出:

代码语言:javascript
复制
a,b,c,d,e,f,g,h,i,jkl,m,n,o,p
票数 3
EN

Stack Overflow用户

发布于 2018-03-07 00:36:32

如果perl没问题-可以像awk一样用于流处理

代码语言:javascript
复制
$ cat ip.txt 
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
1,2,3,4,5,6,3,4,2,4,3,4,3,2,5,2,3,4
1,2,3,4,5,6,3,4,2,4,a,s,f,e,3,4,3,2,5,2,3,4
$ awk -F, '{print NF}' ip.txt 
16
18
22

$ perl -F, -lane '$n = $#F - 4;
                  print join ",", (@F[0..8], join("", @F[9..$n]), @F[$n+1..$#F])
                 ' ip.txt
a,b,c,d,e,f,g,h,i,jkl,m,n,o,p
1,2,3,4,5,6,3,4,2,43432,5,2,3,4
1,2,3,4,5,6,3,4,2,4asfe3432,5,2,3,4

  • -F, -lane对保存在array
  • $n = $#F - 4幻数中的,结果进行@F拆分,以确保输出以14列结束。$#F提供数组最后一个元素的索引(如果输入行少于14个,则不起作用) columns)
  • join帮助使用前9个elements
  • @F[9..$n]将数组元素与指定的string
  • @F[0..8]数组切片缝合在一起,并根据需要对其他切片执行@F[$n+1..$#F]

Ed Morton's regex based solution借用

代码语言:javascript
复制
$ perl -F, -lape '$n=$#F-13; s/^([^,]*,){9}\K([^,]*,){$n}/$&=~tr|,||dr/e' ip.txt
a,b,c,d,e,f,g,h,i,jkl,m,n,o,p
1,2,3,4,5,6,3,4,2,43432,5,2,3,4
1,2,3,4,5,6,3,4,2,4asfe3432,5,2,3,4

  • $n=$#F-13 magic number
  • ^([^,]*,){9}\K前9个fields
  • ([^,]*,){$n}字段到change
  • $&=~tr|,||dr使用commas
  • e删除tr此修饰符允许在替换部分中使用Perl代码
  • 此解决方案还有一个额外的优势,即使输入字段小于14

也可以工作

票数 2
EN

Stack Overflow用户

发布于 2018-03-07 01:15:04

使用GNU awk进行第三个参数的匹配()和gensub():

代码语言:javascript
复制
$ cat tst.awk
BEGIN{ FS="," }
match($0,"(([^,]+,){9})(([^,]+,){"NF-14"})(.*)",a) {
    $0 = a[1] gensub(/,/,"","g",a[3]) a[5]
}
{ print }

$ awk -f tst.awk file
a,b,c,d,e,f,g,h,i,jkl,m,n,o,p
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49135518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档