プロが教えるわが家の防犯対策術!

引数で指定されたディレクトリ配下のファイル全てに置換処理を行う
処理をC言語で作成したいと考えています。
ディレクトリ配下には、最大で100MB位のファイルが約100件存在する
想定です。
(ファイルのサイズ、件数は実行毎に異なります。)
そこで2点ほど教えていただきたいことがあります。

1.基本的に、UNIXコマンドのtrコマンドでで置換するより、C言語で
  全てのファイルを開き1行ずつ、「置換文字列のチェック」→
  「置換文字列が存在すれば置換」→「ファイル書込み」と行った
  ほうが早いものでしょうか?
  (trコマンドを実行したところ、10分待っても処理が完了しませんでした。)

2.C言語にてディレクトリ配下のファイル名を取得し、ファイルの
  件数分ループさせるにはどのようにすればよいのでしょうか?
  execコマンドにて「ls -l test.txt | awk '{print $○}'」
  (ファイル名のみ取得)の結果をファイルに出力し、そのファイル
  からファイル名を取得し、EOFになるまでループすることで出来る
  と思いますが、この方法は一般的でしょうか?
  出来れば余計なファイルは、作成したくないと考えています。

ご回答の方、よろしくお願いします。

A 回答 (4件)

「速度」は、大して変わらない。

作り方が下手だと、Cの方が遅い。
と思います。

・コマンドは、プログラムに詳しい人が、効率等も考慮した上で作ったものです。
ソースコードはCやC++で書かれたものがほとんどです。
新たにCで作ったところで、同レベルのものにしかなりません。
下手すれば効率の悪いアルゴリズムにより遅くなります。

・複数のコマンドを実行するとき、プロセス生成というオーバーヘッドがかかります。
その点では、一つのプロセスで全部やるようなCのプログラムを作る、というのは有利になります。
しかし、最近のコンピュータの性能、そして今回やりたい処理が「CPUやメモリに比べてとても遅い」ファイル操作だということを考慮すると、このオーバーヘッドによる影響は少ないと予想されます。



また、配布を考えた場合、バイナリの実行ファイルだと、構成の違う装置で実行できない場合があります。
これを防ぐにはソースコードでの配布が必要でしょう。
シェルスクリプトや、Perlスクリプトでは、環境の違いに対しての影響が少ないです
    • good
    • 0
この回答へのお礼

お礼が遅れてしまい申し訳ありませんでした。
sedを使用し、ツールとして求められている性能を
満たすことが出来ました。
また、sedが使用できるため汎用的に使用できる
シェルスクリプトでの開発を行いました。
様々なアドバイスありがとうございました。

お礼日時:2013/12/23 20:15

#2 でも書かれているように, この例だと実行時間のほとんどは「ファイルの読み書き」に費やされます. そのことを念頭に置くと


・頑張って書けば C で書く方が速い (逆に言えば「頑張らないと勝てない」)
・ただしその違いはほとんど無視できる程度 (どうがんばっても「ファイルの読み書きに費やす時間」は変わらないので)
だと思います. 「プロセスの生成にかかる時間」も, Perl 等なら変わらないと思っていいでしょう (1つのプロセスで全ファイルに対して置換すればいいだけ).

ちなみに「C言語にてディレクトリ配下のファイル名を取得し、ファイルの件数分ループさせる」のは Unix なら dirent.h を #include して opendir/readdir/closedir が常套手段, かな.
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
やはりツールとC言語で作成したプログラム
とではそんなに性能が変わらないようですね。

「opendir/readdir/closedir」は、初めて知った
関数です。
今後使用させていただきます。
ありがとうございました。

お礼日時:2013/12/23 20:35

質問に書かれている機能は、Windowsシステム上ではプログラマ等に一番よく使われている秀丸エディタの標準組み込みコマンドで簡単に実行出来ます。



grep機能、grepして置換の機能等があります。
キー割り当てをしておけばワンアクションでgrepして置換の機能が呼び出せます。

検索/置換文字列の指定、検索するフォルダの指定、サブフォルダの指定等が可能です。
数百MBの複数の大容量ファイルでも高速に処理可能です。

シェアウェアですが、フル機能版のダウンロードテスト実行が可能です。
(数十年前から使っていますが最新版もそのまま使用でき、結局自分の場合年間使用料は50円?程度にしかならない計算です)

サポート会議室やユーザー作成のマクロ等も便利に使えます。

http://www.forest.impress.co.jp/library/software …
http://www.maruo.co.jp/hidesoft/2/indexg.html
http://hide.maruo.co.jp/lib/macro/index.html

先ずは対応ディレクトリ以下のファイルを別の場所にコピーしてテスト実行をしてみて下さい。

次のように辿って指定し、実行出来ます。
その他
コマンド一覧
検索系
grepして置換
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
なるほど。エディタでの対応は、考えていませんでした。
ただ、Windows上の開発ですとLINUX、Windows間の
データ移動が発生するため今回は見送らせていただきます。
すみません。
今後参考にさせていただきたいと思います。

お礼日時:2013/12/23 20:25

少なくとも、今この程度の質問をしているあなたがCのプログラムを完成させるより、


trコマンド等で処理した方が、「早く」終わるでしょう。


trコマンドは 「文字A」 を 「文字B」 へ変換するコマンドです。
tr ABC abc < file1
で file1の Aをaに、Bをbに、Cをcに、変換します。
入力ファイルは標準入力で指定するしかありません。
http://linuxjm.sourceforge.jp/html/GNU_textutils …

「10分かかっても終らない」とは
tr abcABC fie1
等と、ファイル名が置換パターンとして認識されるようなコマンドラインで実行しているのではないでしょうか?
そのため、標準入力が端末からの入力となり、キーボードでの入力を待っている状態ではないでしょうか?

また、置換というと「文字列A」 を「文字列B」へ変更するようなことです。
tr の「文字から文字へ」という変換が、あなたがやりたいことなのでしょうか?
「文字列から文字列へ」の変換なら、trではできません。 sed の方が一般的でしょう。

「日本語」での置換となると、少しやっかいです。 特にShift_JISはやっかいです。
Perl,php等のマルチバイトに対応したスクリプト言語を使うのがよいでしょう。

ディレクトリ配下にあるファイルを探すには、 find コマンドが定番です。
特に, -file , -exec と組合せて、「指定したディレクトリ配下にある特定のファイル名のファイルに対して、特定のコマンドを実行する」というコマンドを実行できます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
申し訳ありません。
お恥ずかしい限りです。
したい事は、上記でいわれている「文字列A」 を「文字列B」に
変換する置換です。trコマンドを使用する事がそもそも間違いでした。
また、「find」の使用が定番であるということも勉強になりました。
今回作成しようとしているプログラムは今後ツールとして提供しようとしているものなので、UNIXコマンドとC言語のプログラムでの置換どちらの方が処理が早いのかが気になり質問させていただきました。

お礼日時:2013/12/08 17:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!