【问题标题】:Change the value of specific cell in CSV using bash使用 bash 更改 CSV 中特定单元格的值
【发布时间】:2021-02-20 02:01:04
【问题描述】:

我想使用 bash 命令行更改 CSV 中特定单元格的值。

我有一个 Sellers.csv:

seller_id,seller_zip_code_prefix,seller_city,seller_state
3442f8959a84dea7ee197c632cb2df15,13023,campinas,SP
723a46b89fd5c3ed78ccdf039e33ac63,93310,novo hamburgo, rio grande do sul, brasil,RS

如您所见,第 3 行第 3 列 (seller_city) 违反了规则,因为它包含逗号。这就是 MySQL 说“第 3 行包含的数据多于输入列”的原因。 我想将novo hamburgo, rio grande do sul, brasil 更改为novo hamburgo rio grande do sul brasil。 我试过awk,但它说我提供了错误的论点。

awk -v r=553 -v c=3 -v val="novo hamburgo - rio grande do sul - brasil" -F sellers.csv

awk:选项需要一个参数 -- F

【问题讨论】:

  • -F 选项有什么用?文档是怎么说的?
  • -F 是字段分隔符赋值。

标签: bash csv awk syntax


【解决方案1】:

最简单的选择是使用 | 而不是 , 生成 csv 文件。 这个解决方案可以避免这个问题。

标准的csv 将字符串放在" 引号中,以避免内部,

看到这个question

【讨论】:

  • 你是绝对正确的:CSV 将字符串放在 " 引号中。这就是 MySQL 将 CSV 中的一些整数值作为字符串读取的原因。为了解决这个问题,我不得不从 CSV 中删除引号。我这样做了使用 bash 命令: awk '{gsub(/\"/,"")};1' input.csv 但它导致另一个错误。在第 553 行中,seller_city 的值为novo hamburgo, rio grande do sul, brasil。这就是 MySQL 给出错误的原因:“第 553 行包含的数据多于输入列”。为了解决这个问题,我不得不寻找用空字符串替换逗号的解决方案。
【解决方案2】:

您不需要替换逗号,只需引用您的字段:

$ awk -F',' -v OFS='","' '{city=$0; sub(/([^,]*,){2}/,"",city); sub(/,[^,]*$/,"",city); print "\"" $1, $2, city, $NF "\""}' sellers.csv
"seller_id","seller_zip_code_prefix","seller_city","seller_state"
"3442f8959a84dea7ee197c632cb2df15","13023","campinas","SP"
"723a46b89fd5c3ed78ccdf039e33ac63","93310","novo hamburgo, rio grande do sul, brasil","RS"

但如果你真的不想这样做,你可以这样做:

$ awk 'BEGIN{FS=OFS=","} {city=$0; sub(/([^,]*,){2}/,"",city); sub(/,[^,]*$/,"",city); gsub(/ *, */," - ",city); print $1, $2, city, $NF}' sellers.csv
seller_id,seller_zip_code_prefix,seller_city,seller_state
3442f8959a84dea7ee197c632cb2df15,13023,campinas,SP
723a46b89fd5c3ed78ccdf039e33ac63,93310,novo hamburgo - rio grande do sul - brasil,RS

有关其他任何内容,请参阅What's the most robust way to efficiently parse CSV using awk?

【讨论】:

  • 感谢您的回答!最初,我删除了引号。标准 CSV 将字符串放在 " 引号中以避免内部 ',' 。这就是 MySQL 将 CSV 中的一些整数值作为字符串读取的原因。为了解决这个问题,我必须从 CSV 中删除引号。我使用 bash 命令执行此操作: awk '{gsub(/\"/,"")};1' input.csv 但它导致了另一个错误。在第 553 行中,seller_city 的值为novo hamburgo, rio grande do sul, brasil。这就是 MySQL 给出错误的原因:“第 553 行包含的数据多于输入列”。现在我应该解决这个问题。我会试试你的建议
  • 不客气。以这种方式删除引号是一个非常糟糕的主意,它会产生更严重的问题,我相信你现在很感激!请参阅stackoverflow.com/help/someone-answers 了解下一步操作。
【解决方案3】:

这可能对你有用(GNU sed):

sed ':a;s/,/&/4;T;s// -/3;ta' file

如果当前行有四个,,则将第三个替换为 - 并重复直到失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    相关资源
    最近更新 更多