引数で指定されたディレクトリ配下のファイル全てに置換処理を行う
処理をC言語で作成したいと考えています。
ディレクトリ配下には、最大で100MB位のファイルが約100件存在する
想定です。
(ファイルのサイズ、件数は実行毎に異なります。)
そこで2点ほど教えていただきたいことがあります。
1.基本的に、UNIXコマンドのtrコマンドでで置換するより、C言語で
全てのファイルを開き1行ずつ、「置換文字列のチェック」→
「置換文字列が存在すれば置換」→「ファイル書込み」と行った
ほうが早いものでしょうか?
(trコマンドを実行したところ、10分待っても処理が完了しませんでした。)
2.C言語にてディレクトリ配下のファイル名を取得し、ファイルの
件数分ループさせるにはどのようにすればよいのでしょうか?
execコマンドにて「ls -l test.txt | awk '{print $○}'」
(ファイル名のみ取得)の結果をファイルに出力し、そのファイル
からファイル名を取得し、EOFになるまでループすることで出来る
と思いますが、この方法は一般的でしょうか?
出来れば余計なファイルは、作成したくないと考えています。
ご回答の方、よろしくお願いします。
No.2ベストアンサー
- 回答日時:
「速度」は、大して変わらない。
作り方が下手だと、Cの方が遅い。と思います。
・コマンドは、プログラムに詳しい人が、効率等も考慮した上で作ったものです。
ソースコードはCやC++で書かれたものがほとんどです。
新たにCで作ったところで、同レベルのものにしかなりません。
下手すれば効率の悪いアルゴリズムにより遅くなります。
・複数のコマンドを実行するとき、プロセス生成というオーバーヘッドがかかります。
その点では、一つのプロセスで全部やるようなCのプログラムを作る、というのは有利になります。
しかし、最近のコンピュータの性能、そして今回やりたい処理が「CPUやメモリに比べてとても遅い」ファイル操作だということを考慮すると、このオーバーヘッドによる影響は少ないと予想されます。
また、配布を考えた場合、バイナリの実行ファイルだと、構成の違う装置で実行できない場合があります。
これを防ぐにはソースコードでの配布が必要でしょう。
シェルスクリプトや、Perlスクリプトでは、環境の違いに対しての影響が少ないです
お礼が遅れてしまい申し訳ありませんでした。
sedを使用し、ツールとして求められている性能を
満たすことが出来ました。
また、sedが使用できるため汎用的に使用できる
シェルスクリプトでの開発を行いました。
様々なアドバイスありがとうございました。
No.4
- 回答日時:
#2 でも書かれているように, この例だと実行時間のほとんどは「ファイルの読み書き」に費やされます. そのことを念頭に置くと
・頑張って書けば C で書く方が速い (逆に言えば「頑張らないと勝てない」)
・ただしその違いはほとんど無視できる程度 (どうがんばっても「ファイルの読み書きに費やす時間」は変わらないので)
だと思います. 「プロセスの生成にかかる時間」も, Perl 等なら変わらないと思っていいでしょう (1つのプロセスで全ファイルに対して置換すればいいだけ).
ちなみに「C言語にてディレクトリ配下のファイル名を取得し、ファイルの件数分ループさせる」のは Unix なら dirent.h を #include して opendir/readdir/closedir が常套手段, かな.
ご回答ありがとうございます。
やはりツールとC言語で作成したプログラム
とではそんなに性能が変わらないようですね。
「opendir/readdir/closedir」は、初めて知った
関数です。
今後使用させていただきます。
ありがとうございました。
No.3
- 回答日時:
質問に書かれている機能は、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して置換
ご回答ありがとうございます。
なるほど。エディタでの対応は、考えていませんでした。
ただ、Windows上の開発ですとLINUX、Windows間の
データ移動が発生するため今回は見送らせていただきます。
すみません。
今後参考にさせていただきたいと思います。
No.1
- 回答日時:
少なくとも、今この程度の質問をしているあなたが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 と組合せて、「指定したディレクトリ配下にある特定のファイル名のファイルに対して、特定のコマンドを実行する」というコマンドを実行できます。
ご回答ありがとうございました。
申し訳ありません。
お恥ずかしい限りです。
したい事は、上記でいわれている「文字列A」 を「文字列B」に
変換する置換です。trコマンドを使用する事がそもそも間違いでした。
また、「find」の使用が定番であるということも勉強になりました。
今回作成しようとしているプログラムは今後ツールとして提供しようとしているものなので、UNIXコマンドとC言語のプログラムでの置換どちらの方が処理が早いのかが気になり質問させていただきました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA★PDFをPDFアプリで印刷しようと思っていますが上手くゆきません 1 2022/06/06 22:04
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- C言語・C++・C# exeファイルが作れない(windows10) 6 2022/08/13 08:47
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- その他(プログラミング・Web制作) python OpenPyXLを使って出力結果をエクセルに書き込み 2 2022/06/04 19:46
- その他(開発・運用・管理) 【至急】.htaccessによるディレクトリ単位でのリダイレクト 2 2023/08/10 13:46
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- UNIX・Linux Linuxについて質問です。 以下のhistoryの出力結果から、sedコマンドのファイル名tmp1 1 2023/02/03 20:11
- UNIX・Linux テキストファイルをページ番号付きでコマンドラインから印刷したい 1 2023/02/22 12:47
- Visual Basic(VBA) 【VBA】印刷マクロのループ処理が反映されません 3 2022/08/09 02:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コマンドプロンプトをクリック...
-
バッチ終了時にDOS窓を閉じるコ...
-
バッチファイル 文字列にスペ...
-
ショートカットをデスクトップ...
-
make test って何をするための...
-
ftpコマンドを実行すると「425 ...
-
バッチファイルを使ってテキス...
-
コマンドプロンプトで、特定の...
-
VB.NETでのDOSコマンドを実行に...
-
コマンドプロンプトでファイル...
-
シェルの「:コマンドが見つか...
-
C言語のsystem関数でコマンドの...
-
コマンドプロンプトとCygwinの違い
-
2つ目の「pause」は無効?
-
AccessVBAで実行時間を指定する...
-
コマンドプロンプトを最小化し...
-
Pythonで単純にファイルを結合...
-
findstrでヒットした1行前の文...
-
【LINUX】sudoコマンドについて
-
VS2019のコンソールC++からGn...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチ終了時にDOS窓を閉じるコ...
-
バッチファイル 文字列にスペ...
-
ショートカットをデスクトップ...
-
make test って何をするための...
-
コマンドプロンプトをクリック...
-
バッチコマンドのIF文(条件...
-
シェルの「:コマンドが見つか...
-
findstrでヒットした1行前の文...
-
ftpコマンドを実行すると「425 ...
-
Pythonで単純にファイルを結合...
-
コマンドプロンプトで、特定の...
-
コマンドプロンプトでファイル...
-
コンピュータ名をファイル名に...
-
バッチファイルを使ってテキス...
-
SSH接続でwindowsサーバのコマ...
-
バッチファイルで実行コマンド...
-
フォルダ、ファイル操作に最適...
-
バッチファイルでdiskpart.exe...
-
2つ目の「pause」は無効?
-
AccessVBAで実行時間を指定する...
おすすめ情報