【问题标题】:Text processing using awk when separator is part of word? [duplicate]当分隔符是单词的一部分时使用awk进行文本处理? [复制]
【发布时间】:2018-09-17 22:23:40
【问题描述】:

我有一个包含 11 列内容相似的 CSV 文件

 SE Australia|PRM|2017-09-07T16:11:33|2641|-5537383165259899960|2017-09-07T16:12:17|"AU en2|networking-locator"|-|SC7_Electricians_Installer (only provides labor)|p-0715125|1

我正在尝试使用 awk 来分隔每一列,问题是在 1000 万条记录中的某些句子中,分隔符(pip)是单词的一部分。正如您在下面看到的,pip 包含在文本 “AU en2|networking-locator” 中。使用以下命令会返回错误信息。

awk -F "|" '{print $4"_"$6"_"$7"_"$10}'

结果

2641_2017-09-07T16:12:17_"AU en2_p-0715125

异常结果,

2641_2017-09-07T16:12:17_"AU en2|networking-locator"_p-0715125

正如您所见,AU en2 被视为一个单独的列,但是,它是 AU en2|networking-locator 的一部分。如何更改 awk 命令以覆盖这些列?

【问题讨论】:

  • 您的样本输入和样本输出不清楚?请用代码标签更清楚地发布它们,然后让我知道。
  • @RavinderSingh13 我说清楚了。
  • 现在请检查我的代码,如果这对您有帮助,请告诉我?
  • @EdMorton 这是一个错误,我已经编辑过了。对不起。

标签: linux awk text-processing


【解决方案1】:

为此,您需要 GNU awk。使用gawk,您可以使用FPAT 变量:

gawk '{print $4,$6,$7,$10}' OFS=_ FPAT='"[^"]+"|[^|]+' file

使用FPAT,您可以告诉 awk 字段的外观,而不是受限于指定字段分隔符。

在上面的例子中,我们告诉一个字段要么是一个",后跟一个或多个非"字符和一个结束"一个非|的序列字符。这些规则将按照优先级更高的顺序进行评估。

输出:

2641_2017-09-07T16:12:17_"AU en2|networking-locator"_p-0715125

PS:上述解决方案比固定字符分割要慢。由于您的文件有 1 亿行长,因此处理可能需要很长时间。

如果文件仅在 $7 位置包含 "abc|xyz" 字段并且在这种情况下只有一个 | 是安全的。 7 美元,那么你可以使用这个 hack:

awk -F\| '$7~/"/{$7=$7"|"$8;$10=$11}{print $4,$6,$7,$10}' OFS=_ file

它应该比上述解决方案快得多,但它仅在上述情况下有效。您已被警告!

【讨论】:

  • 看起来 awk 使用此参数在处理大量数据时工作非常缓慢。我从 20 分钟前开始执行该命令,并且仍在工作。使用 awk,相同的文件将在 3 分钟内处理完毕。
  • 当然,用复杂的正则表达式分割比用固定字符分割需要更多的努力。您必须等待(与您使用的编程语言无关,而且 awk 已经非常快了)如果您可以更改流程,请确保使用不属于数据的字段分隔符。
  • @MaryamPashmi 我添加了一个更快的解决方案。但请检查它的要求。
  • 如果您设置 OFS 并在输出字段之间使用逗号而不是使用带有硬编码下划线的字符串连接(一个缓慢的操作),第一个可能会快一点。
  • 好点!改变了...
猜你喜欢
  • 2013-08-17
  • 2022-11-12
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
相关资源
最近更新 更多