【问题标题】:How can I check that a column in a tab-delimited file has valid values?如何检查制表符分隔文件中的列是否具有有效值?
【发布时间】:2009-10-16 00:56:11
【问题描述】:

我有一个名为 CHECKME 的大文件,它是制表符分隔的。每行有 8 列。第 4 列是整数。

通过使用 Perl 或 Python,是否可以验证 CHECKME 中的每一行有 8 列,并且第 4 列是整数?

【问题讨论】:

  • 条件CHECKME中每一行有8列,第4列全是整数。
  • 第4列可以有负整数吗?
  • 是的..它将有负整数
  • 即使您已经得到了答案,但如果您显示这些线条以增强问题,将会有所帮助。

标签: python perl


【解决方案1】:

在 Perl 中

while(<>) {
    my @F=split/\t/;
    die "Invalid line: $_" if @F!=8 or $F[3]!~/^-?\d+$/;
}

【讨论】:

  • 来吧,使用一些空格,有 Python 人在看!
  • 前两行有命令行标志,所以这真的是单行!折腾美元。帮助找到有问题的线路。 perl -a -F\\t -ne 'die "line $. invalid: $_" if @F!=8 or $F[3]!~/^-?\d+$/'
【解决方案2】:

在 Python 中:

def isfileok(filename):
  f = open(filename)
  for line in f:
    pieces = line.split('\t')
    if len(pieces) != 8:
      return False
    if not pieces[3].isdigit():
      return False
  return True

我假设“第 4 列”是指第 4 列,因此 [3] 因为 Python(与大多数计算机语言一样)从 0 开始索引。

在这里,我只是返回一个布尔结果,但我拆分了代码,因此很容易就哪一行出错以及如何出错提供良好的诊断,如果您愿意的话。

【讨论】:

    【解决方案3】:

    这对 Perl 来说很容易:

    perl -F\\t -ane'die"Invalid!"if@F!=8||$F[3]!~/^-?\d+$/' CHECKME
    

    【讨论】:

      【解决方案4】:

      在 Perl 中:

      while (<>) {
        if (! /^[^\t]+\t[^\t]+\t[^\t]+\t\d+\t[^\t]+\t[^\t]+\t[^\t]+\t[^\t]+$/) {
          die "Line $. is bad: $_";
        }
      }
      

      检查该行是否以一个或多个非制表符开头,然后是一个制表符,然后是一个或多个非制表符,然后是一个制表符,然后是一个或多个非制表符,然后是制表符, 后跟一个或多个数字等,直到第八组非制表符,它必须在行尾。

      这是快速而肮脏的解决方案,但从长远来看,最好使用“split /\t/”并计算它获得的字段数,然后检查以确保字段 3(零起源)只是数字。这样,当(不是如果)需求发生变化并且您现在需要 9 个字段时,第 9 个字段是质数,就很容易进行更改。

      【讨论】:

      • 哇,这真是一个很长的正则表达式。
      • [^\t]+\t[^\t]+\t 可以替换为 (?:[^\t]+\t){2},推断更多
      【解决方案5】:

      验证输入.py

      读取命令行或标准输入中给出的文件。打印无效行。如果没有错误,则返回代码为零,否则返回代码。

      import fileinput, sys
      
      def error(msg, line):
          print >> sys.stderr, "%s:%d:%s\terror: %s" % (
              fileinput.filename(), fileinput.filelineno(), line, msg)
          error.count += 1
      error.count = 0
      
      ncol, icol = 8, 3
      for row in (line.split('\t') for line in fileinput.input()):
          if len(row) == ncol:
              try: int(row[icol])
              except ValueError:
                  error("%dth field '%s' is not integer" % (
                      (icol + 1), row[icol]), '\t'.join(row))
          else:
              error('wrong number of columns (want: %d, got: %d)' % (
                  ncol, len(row)), '\t'.join(row))
      
      sys.exit(error.count != 0)
      

      示例

      $ 回声 1 2 3 | python 验证输入.py *.txt - not_integer.txt:2:a b c 1.1 e f g h 错误:第 4 个字段“1.1”不是整数 wrong_cols.txt:3:a b 错误:错误的列数(想要:8,得到:3) :1:1 2 3 错误:错误的列数(想要:8,得到:1)

      【讨论】:

        【解决方案6】:

        以下 Python 代码应显示您指定的行:

        for n,line in enumerate(open("filename")):
            line=line.split()
            if len(line)!=8: 
                print "line %d error" % n+1        
            if not line[3].isdigit(): 
                print "line %d error" % n+1
        

        【讨论】:

          猜你喜欢
          • 2019-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-30
          • 2013-06-06
          • 1970-01-01
          • 2013-12-07
          • 1970-01-01
          相关资源
          最近更新 更多