代码之家  ›  专栏  ›  技术社区  ›  andrewj

Linux中以制表符分隔的文件转换为csv的最快方法

  •  41
  • andrewj  · 技术社区  · 16 年前

    我有一个以制表符分隔的文件,有超过2亿行。在Linux中,将其转换为csv文件的最快方法是什么?这个文件确实有多行标题信息,我需要在路上删除这些信息,但是标题的行数是已知的。我已经看到了 sed gawk 但是我想知道是否有一个“首选”的选择。

    只是澄清一下,这个文件中没有嵌入的选项卡。

    9 回复  |  直到 16 年前
        1
  •  42
  •   Mark Rushakoff    16 年前

    如果你只需要 翻译 所有制表符到逗号字符, tr 可能是要走的路。

    这里的空白是一个文字标签:

    $ echo "hello   world" | tr "\\t" ","
    hello,world
    

    当然,如果在文件中的字符串文本中嵌入了制表符,那么也会错误地翻译这些制表符;但是嵌入的文本制表符将非常少见。

        2
  •  71
  •   Ignacio Vazquez-Abrams    16 年前

    如果你担心嵌入的逗号,那么你需要使用稍微智能一点的方法。下面是一个python脚本,它从stdin获取tsv行,并将csv行写入stdout:

    import sys
    import csv
    
    tabin = csv.reader(sys.stdin, dialect=csv.excel_tab)
    commaout = csv.writer(sys.stdout, dialect=csv.excel)
    for row in tabin:
      commaout.writerow(row)
    

    从shell运行它,如下所示:

    python script.py < input.tsv > output.csv
    
        3
  •  19
  •   pabs    16 年前
    perl -lpe 's/"/""/g; s/^|$/"/g; s/\t/","/g' < input.tab > output.csv
    

    Perl在这方面通常比Sed、Awk和Python更快。

        4
  •  6
  •   John Carter    14 年前
    sed -e 's/"/\\"/g' -e 's/<tab>/","/g' -e 's/^/"/' -e 's/$/"/' infile > outfile
    

    该死的批评家,引用所有的话,csv不在乎。

    <tab> 是实际的制表符。\不是为我工作。在bash中,使用^v输入。

        5
  •  5
  •   jtlai    11 年前

    @伊格纳西奥·瓦兹奎兹·艾布拉姆斯的巨蟒解决方案很棒!对于希望解析分隔符其他选项卡的人员,库实际上允许您设置任意分隔符。以下是我的修改版本,用于处理管道分隔文件:

    import sys
    import csv
    
    pipein = csv.reader(sys.stdin, delimiter='|')
    commaout = csv.writer(sys.stdout, dialect=csv.excel)
    for row in pipein:
      commaout.writerow(row)
    
        6
  •  5
  •   Supun Wijerathne    9 年前
    • 如果要将整个TSV文件转换为CSV文件:

      $ cat data.tsv | tr "\\t" "," > data.csv
      

    • 如果要省略某些字段:

      $ cat data.tsv | cut -f1,2,3 | tr "\\t" "," > data.csv
      

      上述命令将把data.tsv文件转换为data.csv文件。 只包含前三个 领域。

        7
  •  3
  •   ghostdog74    16 年前

    假设您不想更改标题,假设您没有嵌入的选项卡

    # cat file
    header  header  header
    one     two     three
    
    $ awk 'NR>1{$1=$1}1' OFS="," file
    header  header  header
    one,two,three
    

    nr>1跳过第一个标题。你提到你知道有多少行的标题,所以请为你自己的案件使用正确的数字。这样,您也不需要调用任何其他外部命令。只有一个awk命令可以完成这项工作。

    另一种方法是,如果你有空的列,并且你关心它。

    awk 'NR>1{gsub("\t",",")}1' file
    

    使用SED

    sed '2,$y/\t/,/' file #skip 1 line header and translate (same as tr)
    
        8
  •  0
  •   coderofsalvation    12 年前

    以下awk oneliner支持引用+引号转义

    printf "flop\tflap\"" | awk -F '\t' '{ gsub(/"/,"\"\"\"",$i); for(i = 1; i <= NF; i++) { printf "\"%s\"",$i; if( i < NF ) printf "," }; printf "\n" }'
    

    给予

    "flop","flap""""
    
        9
  •  0
  •   drmaa    8 年前

    我认为最好不要对文件进行分类,因为对于大文件来说,它可能会造成问题。最好的办法是

    $ tr ',' '\t' < csvfile.csv > tabdelimitedFile.txt

    该命令将从csvfile.csv获取输入,并将结果存储为制表符分隔在tabDelimitedFile.txt中。