Mam kilka plików przecinków w folderze. Linie wyglądają tak ...

1,2,3,4,5
6,7,8
9,10
11,12,13,14,15

Oczekuje się, że wszystkie pliki mają dokładne 5 kolumn. Ale jest kilka plików, w których jedna lub wszystkie linie są mniejsze niż 5, jak pokazano powyżej. Skąd mam znać nazwy takich plików?

Jeśli wszystkie linie mają dokładnie 4 przecinek, nie ma problemu, a takie pliki są uważane za OK.

0
shantanuo 20 wrzesień 2012, 16:27

6 odpowiedzi

Najlepsza odpowiedź

Czy ta linia działa dla Ciebie?

 find . -name *.txt |xargs -I{} awk -F',' 'NF!=5{print FILENAME;exit;}' {}

Załóżmy, że twoje pliki mają rozszerzenie "txt"

aktualizacja

OP chce numerów linii:

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

zaktualizuj ponownie

Op, powinieneś wyraźniej opisać swoje pytanie.

Więc chcesz całkowite numery linii (suma):

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
2
Kent 20 wrzesień 2012, 14:28

W Pythonie:

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
0
Kevin 20 wrzesień 2012, 12:32
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)]
0
MostafaR 20 wrzesień 2012, 12:36

To rozszerzone polecenie GREP powinno działać:

grep -vEl '^[^,]+(,[^,]+){4}$'

Jeśli pliki Gzped możesz użyć Zgrep:

zgrep -vEl '^[^,]+(,[^,]+){4}$'
0
Thor 20 wrzesień 2012, 12:37

Użyłem count, aby policzyć ',' w każdej linii:

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'))
0
mgilson 20 wrzesień 2012, 12:41

Coś takiego ( nb to czeki są 5 kolumn - nie, że są 4 , 's ):

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
1
Jon Clements 20 wrzesień 2012, 12:57