【问题标题】:How to read the comma separated values如何读取逗号分隔值
【发布时间】:2017-10-20 02:55:26
【问题描述】:

我们有一个固定宽度的文件

Col1 length 10
Col2 length 10
Col3 length 30
Col4 length 40

样本记录

ABC       123       xyz.                          5171-5261,51617
ABC.          1234.       Xxy.      81651-61761

Col4 可以有任意数量的逗号分隔值 在 40 个字符的长度内有 1 个或多个:
如果该记录有 1 个值,则输出文件没有变化。 如果存在多个值,即逗号分隔 (5171-5261,51617) 输出文件应该有多个记录。

1 record 
ABC.  123.    Xyz.   5171-5261
ABC     123.   Xyz.   51617

最有效的方法是什么。 截至目前尝试使用 while 和 for 循环,但执行需要很长时间,因为我们通过读取每条记录来进行拆分。

输出文件可以是逗号分隔或固定宽度。

【问题讨论】:

标签: unix awk


【解决方案1】:

awk 是你的朋友。

一行awk就可以实现你所需要的:

awk -v FIELDWIDTHS="10 10 30 40" '{ if (match($4,",")) { split($4,array,","); for (i in array) { print $1,$2,$3,array[i]; }; } else { print $1,$2,$3,$4 }; }' samp.dat 

为了便于阅读代码是:

{
    if (match($4,",")) {
        split($4,array,",");
        for (i in array) {
            print $1,$2,$3,array[i];
        };
    } else {
        print $1,$2,$3,$4 
    };
}

使用您提供的示例数据进行测试:

ABC        123        xyz.                           5171-5261
ABC        123        xyz.                           51617
ABC.           1234.        Xxy.      81651-61761 


它是如何工作的:
awk 一次读取一行文件。
FIELDWIDTHS 指令允许我们将每一列引用为 $1,$2...
现在我们有了我们的列,我们可以在第四个字段中查找逗号match($4,",")
如果我们找到一个,我们会在第四个字段中创建一个值数组,这些值用逗号分隔,split($4,array,",")
然后我们循环遍历这个数组并打印多行输出,每个元素对应一个数组。
如果第四个字段没有逗号,else 子句将打印一行。
对固定宽度文件中的每一行重复此过程。

注意: awk associative arrays 不保证保留数据的顺序。 这意味着您的输出可能会显示为

ABC        123        xyz.                           51617
ABC        123        xyz.                           5171-5261
ABC.           1234.        Xxy.      81651-61761

即输入数据中的5171-5261,51617 在第一个值之前从第二个值产生了一行。

如果排序对您很重要,那么您可以使用下面的代码先从输入数据生成 csv,然后生成保留顺序的输出。

awk -v FIELDWIDTHS="10 10 30 40" '{print $1,$2,$3,$4}' OFS=','  samp.data > samp.csv
awk -F',' '{ for (i=4; i<=NF; i++) { print $1,$2,$3,$i } }' samp.csv

【讨论】:

  • 而且我知道花很多时间回答一个问题却没有得到任何反馈是多么令人沮丧;-)。不错的答案。继续发帖。
猜你喜欢
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
相关资源
最近更新 更多