質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

6回答

3150閲覧

大量のバイナリファイルから破損ファイルの有無,ファイルの存在有無をチェックしたい

loreeeee

総合スコア40

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/03/08 11:22

編集2018/03/08 11:24

あるディレクトリにaaa_2006MMDYHH.binのバイナリファイルが複数あるとします.
MMは月(01,02,...12),DYは日(01,02, ...,[月末日]),HH(00, 01, ..., 23)は時間を表しており,各ファイルのサイズは同じです.
ここで,ファイルが1時間置きに全ての日数分存在しているかどうか,さらにそのなかで破損ファイル(ファイル自体は存在するがファイルサイズがほかと異なる)が存在するかどうかを自動でチェックしたいのですが,何かよい方法はありますか?現在シェルかpythonで組もうとしているのですが各ファイルのファイルサイズを取得する部分でつまづいてます.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

大の月/小の月などを一々条件判定するのはダサイと思い、datetimeにやらせてみることにしました。

Python

1import os.path 2import datetime as dt 3 4dt0 = dt.datetime(2016,1,31,0,0,0) 5dt1 = dt.datetime(2016,12,31,23,0,0) 6filesize = os.path.getsize("aaa_2006010101.bin") 7 8while True: 9 if dt0==dt1: 10 break 11 filename = "aaa_{y:4d}{m:02d}{d:02d}{h:02d}.bin".format(y=dt0.year, m=dt0.month, d=dt0.day, h=dt0.hour) 12 if os.path.exists(filename): 13 if os.path.getsize(filename)!=filesize: 14 print(filename + " looks broken.") 15 else: 16 print(filename + " looks ok.") 17 else: 18 print(filename + " does not exist.") 19 dt0 = dt0 + dt.timedelta(hours=1)

投稿2018/03/08 17:27

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

loreeeee

2018/03/10 06:43

datetimeとos.path.getsize()を使えばここまで綺麗に書けるのですね.とても勉強になりました. ありがとうございます.
guest

0

質問文で一番気になるポイントはファイル書き出し側の処理がos.rename windowsならos.replaceを使ってアトミックにファイルを書き出しているかどうかですが。。。

2案あります。

案1,ファイルサイズでソートしてチェック
ファイルの漏れはファイル数でチェック。

案2,ファイルの日付を生成してループで回してチェック

案2のファイルサイズのチェックまでのコードのサンプルです。

Python

1# -*- coding: utf-8 -*- 2from pathlib import Path 3from datetime import datetime, timedelta 4from collections import Counter 5 6def date_generator(): 7 # 年,月,日,時間 8 current_date = datetime(2006, 1, 1, 0) 9 end_date = datetime(2006, 1, 1, 3) 10 #end_date = datetime(2007, 1, 1, 0) 11 while True: 12 yield current_date 13 current_date += timedelta(hours=1) 14 if current_date == end_date: 15 break 16 17 18def main() -> None: 19 not_founds = [] 20 file_sizes = Counter() 21 for dt in date_generator(): 22 file_name = f"aaa_{dt.strftime('%Y%m%d%H')}.bin" 23 p = Path(file_name) 24 try: 25 st_size = p.stat().st_size 26 file_sizes[st_size] = str(p) 27 except FileNotFoundError as ex: 28 not_founds.append(str(p)) 29 pass 30 # ファイルが存在しない物 31 if len(not_founds) >0: 32 print(not_founds) 33 34 print(file_sizes.most_common(5)) 35 36 37if __name__ == "__main__": 38 main() 39

Note:os.scandirを使う事も検討してみてくださいな。

投稿2018/03/08 17:23

編集2018/03/08 18:00
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

抜けファイルのチェック(bash 4.x以上)

bash

1$ echo 2006{{01,03,05,07,08,10,12}{01..31},{04,06,09,11}{01..30},02{01..28}}|xargs -n1 -I@ echo "echo aaa_@{00..23}.bin"|sort|sh|xargs ls >/dev/null

投稿2018/03/08 14:25

編集2018/03/08 14:26
hichon

総合スコア5737

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ファイルのサイズを表示するPythonのプログラム:

# os.pathというモジュールのgetsize関数を使うので、最初にインポートしておく import os.path  filepath = サイズを調べたいファイルのパス #getsize関数でファイルのサイズを調べて、それを表示 print os.path.getsize(filepath)

こんな感じでファイルのサイズを取得できます。

1年分のバイナリファイルがあるかどうかは、だいたい以下のような感じ(実行、デバッグをしていないコードなので、雰囲気をとらえるのに使ってください)

days = [31,28,31,30,31,30,31,31,30,31,30,31] #各月の日数のリスト。 1月は31日、2月は28日、、、を表したものを用意しておく folderpath = ファイルが置かれているディレクトリのパスを設定 normalfilesize = ファイルの正しいサイズを設定 flag=True #バイナリファイルがちゃんと揃っている事を示すフラグを初期化 For mm in range(12) #月のループ for dy in range(days[mm]) # 日のループ。リストdaysを使うことで月の日数が変化することに対応 for hh in range(24) # 時間のループ #月、日、時間の値から、ファイルパスの文字を作る #rangeを使っているのでmmは0から11まで変わるから、+1して1(月)から12(月)になるようにする。dy,hhも同様 filepath = folderpath + "/" + "aaa_2006" + (mm+1) + (dy+1) + (hh+1) + ".bin" if os.path.exists(filepath): #ファイルが存在する場合 if os.path.getsize(filepath) == normalfilesize: #ファイルサイズが正しい場合 else: ファイルサイズが正しくない場合 flag=False #バイナリファイルのサイズが正しくない # ここにファイルサイズが正しくない場合の処理(エラー処理)を書く else: #ファイルが存在しない場合 flag=False #バイナリファイルがちゃんと揃っていない(欠落がある) # ここにファイルが存在しない場合の処理(エラー処理)を書く if flag: #バイナリファイルがちゃんと揃っていた時の処理を書く (print "OK" とか) else: #バイナリファイルがちゃんと揃っていた時の処理を書く (print "NG" とか)

投稿2018/03/08 13:21

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

とりあえずファイルサイズについて。

ls -l aaa_*.bin| awk '{print $5}'

ぐらいで各ファイルのバイト数の一覧が取れます。そう考えると全ての対象ファイルで同じサイズになっているなら

ls -l aaa_*.bin | awk '{print $5}' | uniq

は結果が1行になるでしょうから

ls -l aaa_*.bin | awk '{print $5}' | uniq | wc | awk '{print $1}'

が1かどうかで判定できるのではないでしょうか。自分はawkを使う癖があるのですが、もっと別の(よりシンプルな)書き方もあると思います。


aaa_*.binというパターンは適当です。必要ならもっと厳密に指定すればよいと思います。

投稿2018/03/08 12:46

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

そういうチェックを行うプログラムを組む。としか言いようがないですねー

「python ファイルサイズ」でぐぐると、いろいろ出てくると思います

投稿2018/03/08 12:33

y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問