【问题标题】:Find and replace a huge list of strings in selected columns of a file在文件的选定列中查找并替换大量字符串
【发布时间】:2018-11-10 21:02:37
【问题描述】:

我有一个大的 CSV 文件 (~1GB) - data.csv
一个包含大量管道分隔字符串列表的变量。
list="abc|def|ghi.........."

目标是在data.csv第2和第3列中搜索list变量中列出的每个字符串,并将其替换为字符串unassigned

以下是我想出的,
awk -v list="$list" 'BEGIN{FS=OFS=","}{gsub(list,"unassigned",$2)}{gsub(list,"unassigned",$3)}1' data.csv > data_new.csv

只要列表很小,它就可以正常工作。一旦列表变量超过 10k 个字符串,它就会抛出错误
/usr/bin/awk: Argument list too long

这里有什么解决方案来处理这个长长的列表吗?也欢迎全新的解决方案。提前致谢。

注意:最好避免循环遍历列表,因为它会降低性能。

【问题讨论】:

  • 即使列表只有 2 个值 list='foo,bar',我也看不到它是如何工作的,因为 gsub 将寻找正则表达式 foo,bar 而不是我的 认为 你想要的是foo|baredit您的问题包括简洁、可测试的样本输入和预期输出,以便我们为您提供帮助。
  • 感谢您的更新。我在这里错过了tr "," "|"。更正了变量数据。
  • 你的行是用|还是,分隔的?
  • data.csv 由 , 分隔,这就是为什么我添加 BEGIN{FS=OFS=","} 将其定义为分隔符

标签: shell csv awk sed gsub


【解决方案1】:

如果您使用的是 bash,请改为这样做:

awk '
BEGIN { FS=OFS="," }
NR==FNR { list=$0; next}
{ gsub(list,"unassigned",$2); gsub(list,"unassigned",$3) }
1' <<<"$list" data.csv > data_new.csv

请参阅 Why do I get "/bin/sh: Argument list too long" when passing quoted arguments?Does "argument list too long" restriction apply to shell builtins?,了解您的原始代码发生了什么以及如何解决问题。

【讨论】:

  • 作业中缺少 "list"。还有NR==1这里可能更好......
  • 试过sn-p但没有数据出来。
  • @karakfa 谢谢,更正了list。 wrt NR==1 vs NR==FNR - 我可以选择任何一种方式,但至少 NR==FNR 让您知道输入来自第一个输入流,所以我稍微更喜欢那个。
  • @OptimusPrime 立即尝试。
  • 结果和以前一样。 data_new.csv 为空。
猜你喜欢
  • 2011-11-14
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
  • 2018-04-14
  • 1970-01-01
相关资源
最近更新 更多