【问题标题】:Conditionally replicate rows of a tabular data file based on value in a column根据列中的值有条件地复制表格数据文件的行
【发布时间】:2019-01-17 21:10:29
【问题描述】:

我有一个具有以下结构的大型 csv 文件:

col1,col2,codes
1,2,aaa__bbb
2,4,aaa__eee
3,4,ccc

第 3 列被编码为三个字符代码,由 '__' 分隔。

我想创建一个新的 csv,它为列代码的每个组件复制行。结果应该是这样的:

col1,col2,codes
1,2,aaa
1,2,bbb
2,4,aaa
2,4,eee
3,4,ccc

这是一个相当大的文件(大约 10G)。如果可能的话,我想在不使用编程语言的情况下执行这个 bash(awk?)。实际文件大约有 3000 列。

【问题讨论】:

  • 欢迎来到 SO。 Stack Overflow 是一个面向专业和狂热程序员的问答网站。目标是您将一些自己的代码添加到您的问题中,以至少显示您为解决这个问题所做的研究工作。
  • 从技术上讲,bash 是一种编程语言,awk 也是如此。避免使用诸如 C 或 Java 之类的编译语言是一回事,但避免使用 perl 或 python 之类的语言来支持 awk 可能并不那么谨慎,具体取决于 csv 文件的内容。 awk 可能可以做到这一点,但它可能会变得有点难看。
  • 没有人能告诉你你做错了什么,因为你没有提供你的代码。请显示相关代码并说明确切的错误。另请参阅How to create a Minimal, Complete, and Verifiable example

标签: linux bash shell awk


【解决方案1】:

执行 awk 命令会产生所需的结果。

awk 'BEGIN{FS=OFS=","}{split($NF,a,/__/);for(i in a){$NF=a[i];print}}' file

【讨论】:

  • 假设第 3 列从来没有像 `"aaa__b,c_ddd" 这样的东西... :)
  • @Tanktalus 我希望如果字段可以包含逗号或换行符,OP 会在发布的示例输入中与我们共享。
  • @oguzismail 您可能希望将其调整为awk 'BEGIN{FS=OFS=","}{n=split($NF,a,/__/);for(i=1;i<=n;i++){$NF=a[i];print}}' file,以便它适用于任意数量的字段,并将按最终字段中值的顺序打印输出行,而不是随机的 (可能是哈希)顺序。
  • @EdMorton 是的,但是,IME,这是许多人直到很久以后才注意到的事情之一。
【解决方案2】:

你可以使用 Perl 单行代码

$ cat joseph.txt
col1,col2,codes
1,2,aaa__bbb
2,4,aaa__eee
3,4,ccc

$ perl -F, -lane ' if($.>1) {  print "$F[0],$F[1],",$_ for(split("__",$F[2])) } ' joseph.txt
1,2,aaa
1,2,bbb
2,4,aaa
2,4,eee
3,4,ccc

$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    • 2018-08-17
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    相关资源
    最近更新 更多