【问题标题】:Replace a value for the nth column in a csv file with sed /awk/any linux tool用 sed /awk/any linux 工具替换 csv 文件中第 n 列的值
【发布时间】:2020-10-13 19:35:32
【问题描述】:

我想将 csv 文件中的第 28 列从 '2020-03-08' 替换为 '2020-03-08 00:00' 。 我试过了:gawk -i inplace -F"," '{sub($28,"&00:00"); print}' $filename。 这会失败,因为 $28 是一个甚至可能为空的日期,因此它会替换文件中的任何值,而不是特定的第 28 列。

此外,2020-03-08 可以出现在 csv 文件中的任何位置,它可以被替换而不是第 28 列。 我该如何解决这个问题?

例如 csv 文件中的一行:

1057481434,e0e529d7-0942-44b1-b26d-794809edb113,2020-03-08 00:20:54+00,2020-03-07 13:50:28+00,fc7557d9-900b-4739-a678-79273dbbcaaf,android,indoor,stationary,100,1774,1774,105,336305e8-abfc-41b6-a07e-50c297c517bc,indoor,f,,,t,,,2020-03-07 13:50:27.539555+00,2020-03-07 13:50:27.539555+00,,31.6838,76.5255,1600,0,2020-03-08,0,,,0,0,0,,"31.6838125,76.52552",America/New_York,ASUS_X00TD,asus,asus,0.8.0,com.pepkit.ssg,83,e172ebc7-a301-4ed0-98a8-d1b852cc2235

【问题讨论】:

  • 顺便说一句,开箱即用的 Awk 不知道如何处理 CSV 文件中的双引号字段。如果您需要进行比这更复杂的处理,可能会切换到具有适当 CSV 解析器的工具,尤其是如果您对 Awk 完全陌生。
  • cool 想避免使用 bash 或 java 重写 csv
  • @divyangshah :我会使用一种已经包含 CSV 解析器的语言。因此,无论如何我都不会在 bash 中这样做。 Java 可能会工作(对 Java 的 CSV 库没有经验),但 Perl 或 Ruby 可以正常工作。请注意,如果输入文件确实是一般意义上的 CSV,那么您使用 awk 的方法并不可靠,因为逗号也可能出现在 inside 字段中,而 awk 无法应对。此外,字段可能包含换行符,您也无法在 awk 中轻松处理。
  • 我没有上述两个问题,所以它很酷,另一方面,即使是 csv 解析器,直到我拥有的知识范围内,不要在特定位置编辑 csv

标签: linux bash awk sed


【解决方案1】:

您正在获取$28 中的字符串并将其替换为行中的任何位置。试试

{ $28 = $28 " 00:00" }1

或者,如果你坚持使用sub

{ sub(/$/, " 00:00", $28) }1

注意第三个参数如何指示要替换的位置,而不是整个输入行。

如果您只想在$28 非空时进行替换,请设置有条件的操作。

$28 { $28 = $28 " 00:00" }1

最后的1 是常用的简写形式

{ print }

回想一下,条件和操作都是可选的。如果条件为空,则无条件执行操作。如果该操作为空,则默认操作是打印当前输入行。唯一的1 是一个始终为真的条件。

【讨论】:

  • 最后的 1 是什么?我尝试了两种方法,它删除了“,为什么?
  • 它是无条件print 的简写。这是一个非常常见的 Awk 习语。
  • 我尝试了两种方法,它删除了“,”,为什么?得到类似的东西 1057481434 e0e529d7-0942-44b1-b26d-794809edb113 2020-03-08 00:20:54+00 2020-03-07 13:50:28+00 fc7557d9-900b-4739-a678-79273d 室内100 1774 1774 105 336305e8-abfc-41b6-a07e-50c297c517bc indoor f t 2020-03-07 13:50:27.539555+00 2020-03-07 13:50:27.539555+00 31.6838 76.5255 1600 0 2020-03-08 00: 00 0 0 0 0 "31.6838125 76.52552" America/New_York ASUS_X00TD asus asus 0.8.0 com.pepkit.ssg 83 e172ebc7-a301-4ed0-98a8-d1b852cc2235
  • 如果要使用逗号作为输出分隔符,请添加BEGIN { OFS=FS }。同样,这在任何 Awk 的介绍中都应该很容易找到。
猜你喜欢
  • 1970-01-01
  • 2014-03-05
  • 2021-10-16
  • 2021-07-24
  • 2018-07-26
  • 2014-09-08
  • 2020-01-17
  • 1970-01-01
  • 2021-03-29
相关资源
最近更新 更多