【问题标题】:How to convert a tab-separated file into a comma-separated file?如何将制表符分隔的文件转换为逗号分隔的文件?
【发布时间】:2010-08-18 05:57:02
【问题描述】:

我想将制表符分隔的文件转换为 CSV 文件。谁能帮帮我?

【问题讨论】:

    标签: csv unix


    【解决方案1】:

    OSX 的答案是不同的。

    MacOS 无法理解 sed 表达式中的 \t

    您必须使用 ctrl+v 然后 tab 将制表符文字插入 sed 搜索模式(请参阅How can I insert a tab character with sed on OS X?

    sed 's/ /,/g' input_file > output_file
    

    【讨论】:

    • 在 OSX 上,您可以使用理解 \t 的 GNU sed。 This question是关于如何安装的。
    • “不同”是什么意思?你还没有说你在比较什么。
    【解决方案2】:

    您可以将 sed 用作:

    sed 's/\t/,/g' input_file > output_file
    

    这将保持输入文件不变,并将创建一个带有更改的新文件output_file

    如果您想更改输入文件本身而不创建新文件,您可以使用-i sed 选项来进行就地更改:

    sed -i 's/\t/,/g' input_file 
    

    【讨论】:

    • 这在 OS X 中不起作用,它似乎匹配字母“t”而不是制表符。
    • 不要在 OSX 上键入 \t,而是按 ctrl + v 然后按 tab
    • @codaddict,如果我可以问,g's/\t/,g' 中是什么意思?
    • @Les g 是启用全局替换.... ref: tutorialspoint.com/unix/unix-regular-expressions.htm "非常重要的是要注意 sed 只替换一行中的第一个出现。如果字符串 root在一行中出现不止一次,只会替换第一个匹配项。要让 sed 执行全局替换,请在命令末尾添加字母 g,如下所示“
    • OSX 使用 bsd 风格的 sed。如果您使用空白文件扩展名 mod,它将起作用。 sed -i '' 's/foo/goo/g' somefile-name -i 后面的空格用单引号括起来。
    【解决方案3】:

    请记住,逗号分隔值文件有多种形式。由于您没有指定一个,我假设RFC-4180 格式,UTF-8 编码,TSV 相同,但使用制表符而不是逗号。

    天真的方法是简单地用逗号替换每个选项卡:

    tr '\t' ,
    

    如果任何值已经包含逗号,或者如果任何值包含带引号的选项卡,则此选项会下降。您需要对文件进行最低限度的解析,以保持引用。与其手动滚动这样的解析器,不如使用已经编写好的解析器更简单、更清晰、更灵活,例如用于 Perl 的 Text::CSV

    #!/usr/bin/perl -w
    
    use Text::CSV;
    
    my $tsv = Text::CSV->new({ sep_char => "\t", auto_diag => 2 });
    my $csv = Text::CSV->new();
    
    while (my $row = $tsv->getline(*ARGV)) {
        $csv->print(STDOUT, $row) or die $csv->error_diag();
        print $/;
    }
    $csv->error_diag() unless $tsv->eof;
    

    【讨论】:

      【解决方案4】:

      这也可以用 Perl 来实现:

      要将结果通过管道传输到新的输出文件,您可以使用以下命令:
      perl -wnlp -e 's/\t/,/g;' input_file.txt > output_file.csv

      如果您想就地编辑文件,可以调用 -i 选项:
      perl -wnlpi -e 's/\t/,/g;' input_file.txt

      如果您偶然发现您正在处理的实际上不是制表符,而是多个空格,您可以使用以下命令将每个出现的两个或多个空格替换为逗号:
      perl -wnlpi -e 's/\s+/,/g;' input_file

      请记住,\s 代表任何空白字符,包括空格、制表符或换行符,不能在替换字符串中使用。

      【讨论】:

        【解决方案5】:

        在 MacOS 中测试后,这适用于将 csv 文件转换为 tsv 文件(假设列值中不存在制表符或逗号):

        cat file_input.tsv | tr '\t' ',' > file_output.csv

        我试过了:

        sed 's/ /,/g' input_file > output_file

        sed 's/\t/,/g' input_file > output_file

        但是,它们都不起作用。

        【讨论】:

        • 为什么是毫无意义的cat?有什么原因你不能tr <file_input.tsv吗?我不明白你为什么发布这个,因为你自己承认它只有在值中没有制表符或逗号时才有效,并且有很多具有相同约束的类似答案。
        【解决方案6】:

        如果 input_file 不包含逗号或带引号的制表符,最简单的方法是使用带有替换正则表达式的 sed 命令,用逗号替换 input_file 中的制表符:

        sed 's/\t/,/g' input_file > output_file
        

        当然,input_files 包含引用的选项卡会混淆正则表达式,还有 input_files 的值包含逗号,这些值应该在 output_files 中引用。上面的正则表达式解决方案不足以解决这些情况。

        在处理输入文件之前,可以考虑几个 bash 命令来“清理”输入文件...

        但是,本着不重新发明轮子的精神。我会使用一个简单的 python3 脚本并将其存储在一个文件中,我们称之为:tsv_to_csv_converter.py:

        import csv
        import sys
        
        tsv_file = sys.argv[1]
        csv_file = sys.argv[2]
        
        in_tsv = csv.reader(open(tsv_file, "r"), delimiter = '\t')
        out_csv = csv.writer(open(csv_file, 'w'))
        
        out_csv.writerows(in_tsv)
        

        当然,这段代码可以通过异常捕获、输入值检查、漂亮的 CLI 界面、文档得到显着改进。

        脚本可以如下使用:

        python3 tsv_to_csv_converter.py input_file output_file
        

        【讨论】:

          【解决方案7】:

          这是通常的简单问题所有语言的事情吗?好的,这是我的 haskell 解决方案:

          main = interact (unlines . replTab . lines) where
            replTab l = l       >>= (\line ->
              "\"" ++ line "\"" >>= \char ->
              case char of
                '\t' -> "\",\""
                '"'  -> "\"\""
                _    -> [char]
              )
          

          未经测试,但应该可以工作。

          PS:所有其他解决方案都不知道转义逗号。

          【讨论】:

            【解决方案8】:

            sed -e 's/TAB_CHAR/,/g' data.tsv > data.csv

            棘手的部分是如何在命令行中输入 TAB 字符,以做到这一点: 只需按“CTRL+V”,然后按 TAB

            我经常将它与带有 -e 参数的 mysql 查询一起使用,如这篇博文 http://blog.modsaid.com/2013/12/exporting-data-from-remote-mysql.html 中所述

            【讨论】:

              【解决方案9】:

              尝试用逗号替换所有选项卡。

              如果您没有任何带引号的字段,则可能使用像 s/\t/,/g 这样的正则表达式。

              或者,您知道,Excel 可以为您做到这一点。或者 R。或者任何可以接受 TSV 文件的东西。

              【讨论】:

                【解决方案10】:

                在 unix 中:

                sed -i -e 's/\t/,/g' filename
                

                【讨论】:

                  猜你喜欢
                  • 2014-04-20
                  • 2015-04-21
                  • 1970-01-01
                  • 2019-04-05
                  • 1970-01-01
                  • 2013-11-14
                  • 2014-05-24
                  • 2020-07-21
                  • 1970-01-01
                  相关资源
                  最近更新 更多