【问题标题】:Convert CSV to TSV将 CSV 转换为 TSV
【发布时间】:2020-01-20 15:51:01
【问题描述】:

如何将此 csv 文件转换为制表符分隔文件?

"Country","Percent","Percent of patients","home health","home health agency","friends and family","Surveys","Response"
"Nation","88","85","83","84","78",,

请注意,Surverys 和 Response 列都是空字符串。

我使用此代码将其转换为选项卡文件 -

sed 's/\"\,\"/\"\t\"/g'
sed 's/\,\,/\t""\t/g'

但它不会转换最后一列。这是我得到的输出(注意最后一列被省略了) -

"Country"   "Percent"   "Percent of patients"   "home health"   "home health agency"    "friends and family"    "Surveys"   "Response"
"Nation"        "88"    "85"    "83"    "84"    "78"    ""

表头有 8 列,制表符分隔的数据只有 7 列,所以漏掉了最后一列。

更新

我的列名中有逗号。

【问题讨论】:

    标签: linux csv sed


    【解决方案1】:

    我确实使用 FPATgnu awk 来处理 CSV 文件

    awk -v FPAT='([^,]+)|("[^"]+")' -v OFS='\t' '{$1=$1}1' file
    "Country"       "Percent"       "Percent of patients"   "home health"   "home health agency"    "friends and family"    "Surveys"       "Response"
    "Nation"        "88"    "85"    "83"    "84"    "78"
    

    不确定最后一列是什么意思。如果它是空的,,,你将看不到它。

    【讨论】:

    • 我的意思是表头有8列,制表符分隔的数据只有7列,所以最后一列被遗漏了。
    • @Aaron 还是不明白。对于缺失的列,您希望得到什么输出?一个空格?一个明星?从其他地方获取数据?
    【解决方案2】:

    实际上,您的最后一列根本没有丢失。你只是看不到它,因为它是一个标签。您可以通过xxd 进行检查。

    此外,您无需在 sed 中转义逗号和双引号,因为您将所有内容都包含在单引号中。

    sed 's/","/"\t"/g; s/,,/\t""\t/g;' $YOUR_CSV | xxd | tail -1.
    

    这表明最后一行以制表符(x09)在最后一个引号之后和结束换行符之前结束:

    00000090: 3834 2209 2237 3822 0922 2209 0a         84"."78".""..
    

    “缺少”的是最后一个空值周围的双引号。但你不需要它们。如果你真的想要这些双引号,你可以将它添加到你的 sed 命令中:

    s/\t$/\t""/
    

    它将用一个制表符后跟两个双引号替换行尾的制表符。

    但是,这个简单的sed 替换当然很容易失败,具体取决于您的数据。

    例如(使用- 而不是\t 以提高可见性),如果您有不在末尾的空列:

    echo '"Nation","88",,,"84","78",,' | sed 's/","/"-"/g; s/,,/-""-/g;'
    

    会输出

    "Nation"-"88"-""-,"84"-"78"-""-
    

    (注意“84”前的逗号)

    所以我建议使用专用工具而不是快速 sed 线。例如,csvtool 在大多数发行版中都可用(sudo apt install csvtool 用于基于 Debian)。

    csvtool -t COMMA -u TAB cat $YOUR_CSV
    

    【讨论】:

      【解决方案3】:

      使用 GNU awk。

      awk 'BEGIN{FS="\",\""; OFS="\t"} {FS=","; for(i=1; i<=NF; i++) {gsub(/"/,"",$i); $i="\"" $i "\""} print}' file
      

      输出:

      “国家”“百分比”“患者百分比”“家庭健康”“家庭健康机构”“朋友和家人”“调查”“回应” “民族”“88”“85”“83”“84”“78”“”“”

      【讨论】:

      • 我的标题中有一个逗号,所以这不起作用。
      • 您的问题中是否缺少这些重要信息?
      • 已添加到问题中。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      • 2019-05-30
      相关资源
      最近更新 更多