我在一个文件夹中有几个逗号分隔的文件。线条看起来像这样...
1,2,3,4,5
6,7,8
9,10
11,12,13,14,15
所有文件都应该有准确的 5 列。但是有一些文件其中一行或所有行少于 5,如上所示。我怎么知道这些文件的名称?
如果所有行都正好有 4 个逗号,那么就没有问题,并且这些文件被认为是好的。
这条线 (find + awk) 对你有用吗?
find . -name *.txt |xargs -I{} awk -F',' 'NF!=5{print FILENAME;exit;}' {}
假设您的文件具有扩展名“txt”
更新
OP想要行号:
kent$ head *.txt
==> 4.txt <==
1,2,3,4,5
6,7,8
9,10
11,12,13,14,15
==> one.txt <==
1,2,3,4,5
6,7,8
9,10
11,12,13,14,15
==> three.txt <==
11,12,13,14,15
==> two.txt <==
11,12,13,14,15
kent$ find . -name *.txt |xargs -I{} awk -F',' 'NF!=5{print FILENAME,NR}' {}
./one.txt 2
./one.txt 3
./4.txt 2
./4.txt 3
再次更新
OP,您应该更清楚地描述您的问题。
所以你想要总行数(总和):
kent$ find . -name *.txt |xargs -I{} awk -F',' 'NF!=5{a[FILENAME]++;} END{if(a[FILENAME]) print FILENAME, a[FILENAME]}' {}
./one.txt 2
./4.txt 2
类似的东西(注意这检查有 5 列 - 不是有 4,
的):
import gzip
from glob import iglob
import csv
for filename in iglob('*.gz'): # or get filenames from wherever
with gzip.open(filename) as fin:
if not all(len(row) == 5 for row in csv.reader(fin)):
print filename
In Python:
def fileIsGood(filename):
for line in open(filename):
if len(line.split(",")) != 5:
return False
return True
fileNames = ["foo.txt", "bar.bat", "baz.exe"]
for fileName in fileNames:
if not fileIsGood(fileName):
print fileName
我会count
用来计算','
每一行的:
import gzip
def is_good(fname):
with gzip.open(fname,'r') as f:
return all( line.count(',') == 4 for line in f )
#somehow get filenames. Here I'll assume glob
good_files = [ fname for fname in glob.glob('*.gz') if is_good(fname) ]
# or if you like functional programming:
#good_files = filter(is_good, glob.glob('*.gz'))
import os
def check_file(name):
with open(name, 'r') as f:
while line = f.readline():
if line.count(',') != 4:
return False
return True
def check(path):
return [filename for filename in os.listdir(path) if not check_file(filename)]
这个扩展的 grep 命令应该可以工作:
grep -vEl '^[^,]+(,[^,]+){4}$'
如果文件经过 gzip 压缩,您可以使用 zgrep:
zgrep -vEl '^[^,]+(,[^,]+){4}$'