【问题标题】:count multiple tabs tsv file计算多个标签 tsv 文件
【发布时间】:2012-08-08 05:45:35
【问题描述】:

我正在尝试解析一个巨大的制表符限制文件(tsv 文件)并将其转换为逗号分隔值文件。 我遇到的问题是,并非 tsv 文件中的所有条目都是完整的,其中一些条目不完整,并且由条目之间的多个制表符间距表示。现在,当我将其转换为 csv 文件时,我希望它们之间有“n.a”,表示该记录字段中没有任何条目。

例如,考虑学生记录示例(1 个制表符 = 4 个空格,请忍受我糟糕的格式)

Name    Age    Department    GPA
Kevin    21    Computer Science    3.4
Tom    20        3.8
Kelsey    22    Psychology        (2 tab spaces here)

在上面的例子中,第一条记录表示字段标题,每一行都是一条记录。 我们可以观察到 Tom 缺少“部门”字段条目,而 Kelsey 缺少“GPA”字段条目。 我的输出应该是这样的:

"Name","Age","Department","GPA"
"Kevin","21","Computer Science","3.4"
"Tom","20","n.a","3.8"
"Kelsey","22","Psychology","n.a"

我的问题:
1)我该如何解决这个问题? Python、java、bash、awk 任何脚本都可以
2)观察“部门”字段下第二行中“计算机”和“科学”之间的空格被忽略并保留。所以生成的脚本不应该计算空格。

完美地做到这一点非常重要,因为我将为搜索索引提供数据。提前致谢。

【问题讨论】:

  • $ awk 'NR>0{$1=$1}1' OFS="," 文件名 > OUTPUT_FILE
  • 恐怕我们在你的粘贴中并没有真正看到标签,所以你应该清楚连续字段之间是否总是有一个标签。

标签: python parsing csv awk tsv


【解决方案1】:

这可以在 python 中非常简单地完成:

import sys
[infile, outfile] = sys.argv[1:]

with open(infile) as inf:
    with open(outfile) as outf:
        for l in inf:
            outf.write(','.join(l.split('\t')).replace(',,',',n.a.,'))

脚本会像这样使用

python convert_csv.py infile outfile

【讨论】:

    【解决方案2】:

    一种使用awk的方式:

    awk '
        ## Split line with tabs, join them in output with commas.
        BEGIN {
            FS = "\t";
            OFS = ",";
        }
    
        ## For each line, check if any field is blank, and substitute with
        ## "n.a". Add double quotes, recompute line and print.
        {
            for ( i = 1; i <= NF; i++ ) {
                if ( $i == "" ) {
                    $i = "n.a";
                }
                $i = "\"" $i "\"";
            }
            $1 = $1;
            print $0;
        }
    ' infile
    

    使用以下输出运行它:

    "Name","Age","Department","GPA"
    "Kevin","21","Computer Science","3.4"
    "Tom","20","n.a","3.8"
    "Kelsey","22","Psychology","n.a"
    

    【讨论】:

    • 优秀。非常感谢。 AWK 是一个很酷的工具来做这些事情。
    【解决方案3】:

    只需在每一行上使用 split('\t')...

    >>> x="a\t\tb"
    >>> x
    'a\t\tb'
    >>> print x
    a               b
    >>> x.split("\t")
    ['a', '', 'b']
    >>>
    

    【讨论】:

      【解决方案4】:

      在python中,

      inputFile = open.("yourFile.tsv", "r")
      outputFile = open.("output.csv", "w")
      
      for line in inputFile:
          entry = line.split("\t")
          for i in range(len(entry)):
              if entry[i] == '':
                  entry[i] = "n.a"
          outputFile.write(",".join(entry))
      
      inputFile.close()
      outputFile.close()
      

      应该可以,虽然它不是特别 Pythonic。

      【讨论】:

      • 这是最好的解决方案。谢谢
      • @crazyim5:只是好奇:为什么是最好的?它使用的行数比我的多,但在逻辑上是一样的。
      • @David 他的代码只是通过复制粘贴和更改文件名来工作,而你的代码没有。这是一种冲动的反应。没关系:)
      猜你喜欢
      • 1970-01-01
      • 2023-02-03
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多