如何检查制表符分隔文件中的列是否具有有效值?

时间:2009-10-16 00:56:11

标签: python perl

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

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

5 个答案:

答案 0 :(得分:4)

在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]来自0。

这里我只是返回一个布尔结果,但是我将代码分开,以便很容易对错误的行提供良好的诊断,以及如果你愿意的话。

答案 1 :(得分:4)

Perl的工作非常简单:

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

答案 2 :(得分:2)

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个字段是素数时,很容易做出改变。

答案 3 :(得分:1)

validate-input.py

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

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)

实施例

$ echo 1 2 3 | python validate-input.py *.txt -
not_integer.txt:2:a b   c   1.1 e   f   g   h
    error: 4th field '1.1' is not integer
wrong_cols.txt:3:a  b   
    error: wrong number of columns (want: 8, got: 3)
<stdin>:1:1 2 3
    error: wrong number of columns (want: 8, got: 1)

答案 4 :(得分:0)

以下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