ファイル結合にあたって文字コードが異なっている可能性もあり、その文字コードも統一する前処理作業も必要なことはわかっているのですが、
Windows8又は、Macintoshでできる方法をお教えいただけると。
(プログラムを書けばいいのは分かるのですが、結構例外が多そうなので、まず出来上がったサンプルファイルを作り、評価をしてからプログラミングをしたいと思いまして)
一回だけの処理なら、単にhtmlファイル名を列挙して、1つにまとめるバッチを作ることで対処できます。
Windowsでコマンドプロンプトからdirコマンドを使うとファイルのリストが得られますが、このときに/b /sオプションをつけると、サブディレクトリも含めた対象ファイルのフルパス名を得られます。
dir /b /s (列挙したいルートディレクトリ)\*.html
上記コマンドの出力を適当なファイルに出力させ、その各行について適当なテキストエディタの置換処理を使って、結合ファイルに追記するようなバッチにして実行すればOKです。
type (HTMLファイルのフルパス名) >> (結合ファイル)
type (HTMLファイルのフルパス名) >> (結合ファイル)
type (HTMLファイルのフルパス名) >> (結合ファイル)
・
・
・
定期的に行う必要がある場合は、上記処理を行うバッチを作ることも可能です。以下のバッチファイルを作って適当なディレクトリから実行すれば、そのディレクトリ以下の全htmlファイルを結合したconnect.txtが生成されます。
@echo off
for /F "delims=" %%F in ('dir /b /s *.html') do (
type %%F >> connect.txt
)
PHPだとこんな感じですかね。サイズが大きいと、うまく行かないかも知れません。
$data = "";
$files = dir(パス);
while (($filename = $files->read()) != FALSE) {
$filepath = (パス) . "/" . $filename;
$data = $data . file_get_contents($filepath);
}
file_put_contents(パス,$data);
Rubyを使えば、ディレクトリ内を再帰的に処理できるようです。
Find.find(パス)で取得できます。
ありがとうございます。
Rubyが一番良さそうな気がして、Rubyを勉強始めています。
丁度やりたいこと全部を出来ることを紹介している本も見つけました。
一回だけの処理なら、単にhtmlファイル名を列挙して、1つにまとめるバッチを作ることで対処できます。
Windowsでコマンドプロンプトからdirコマンドを使うとファイルのリストが得られますが、このときに/b /sオプションをつけると、サブディレクトリも含めた対象ファイルのフルパス名を得られます。
dir /b /s (列挙したいルートディレクトリ)\*.html
上記コマンドの出力を適当なファイルに出力させ、その各行について適当なテキストエディタの置換処理を使って、結合ファイルに追記するようなバッチにして実行すればOKです。
type (HTMLファイルのフルパス名) >> (結合ファイル)
type (HTMLファイルのフルパス名) >> (結合ファイル)
type (HTMLファイルのフルパス名) >> (結合ファイル)
・
・
・
定期的に行う必要がある場合は、上記処理を行うバッチを作ることも可能です。以下のバッチファイルを作って適当なディレクトリから実行すれば、そのディレクトリ以下の全htmlファイルを結合したconnect.txtが生成されます。
@echo off
for /F "delims=" %%F in ('dir /b /s *.html') do (
type %%F >> connect.txt
)
自分も質問のような作業が必要な場合、この手法を使いますね。
付け加えるなら「dir *.html /s /b | clip」とやると、結果がクリップボードに入るので作業用ファイルが不要になります。
Perlでやってみました。スクリプトはUTF-8で保存してください。
use utf8; use strict; use warnings; use Encode; use Path::Class; binmode STDOUT,':encoding(cp932)'; binmode STDERR,':encoding(cp932)'; my $sjis = find_encoding('cp932'); my $out = 'c:/output.txt'; #出力ファイル名 open my $fo,'>:encoding(utf-8)',$out or die "cannot create file<$out>:$!"; my $target = $ARGV[0] || Cwd::getcwd; #引数で指定されなければカレントディレクトリが対象 print "target directory is <$target>\n"; dir($target)->recurse(callback => sub { my $fi = file(shift); my $name = $sjis->decode($fi); return if $name !~ /\.html$/ or -d $name; print "$name\n"; my $buf = $fi->slurp(iomode => '<:encoding(eucjp)'); print $fo $buf; }); close $fo; exit;
ここでは例として、入力ファイルがEUCで書かれていることを想定しています。出力はUTF-8です。画面表示はWindowsということでShiftJISにしています。
文字コードが統一されていないのであれば、それの判別が一番のネックでしょうね。
一応、HTMLファイルの文字コード宣言を読み取ってそれを返してくれるHTML::Encodingなるモジュールもあるようですが、試してはいないのでどれほどのものかはわかりません。
ありがとうございます。
perlがこの手の処理にもっとも向いているのは分かるのですが、なかなか私には敷居が高いですが、最後はここに挑戦してみたいと思います。
勉強になります。ありがとうございました。
Mac では、ターミナルからだと、こんな感じでしょうか。
find /hoge -type f -name "*.html" -print | xargs cat >> output.txt
例外がいろいろあるとのことなので、細かい制御をするなら、bash のスクリプトで。
#! /bin/bash files=`find /hoge -type f -name "*.html" -print` for f in $files do # 例外は、ここではじく if ... then continue fi cat $f >> output.txt done
文字コードを変換する必要があるなら、nkf を使う感じでしょうか。
#! /bin/bash files=`find /hoge -type f -name "*.html" -print` for f in $files do # 例外は、ここではじく ... # UTF-8 に変換して出力 nkf -w $f >> output.txt done
ありがとうございます。
こういう方法があったのですね。
スクリプトでほぼ問題解決できるということ、大変勉強になりました。
(自分の不勉強を恥じるとも言いますか・・・)。
自分も質問のような作業が必要な場合、この手法を使いますね。
2014/09/04 21:56:13付け加えるなら「dir *.html /s /b | clip」とやると、結果がクリップボードに入るので作業用ファイルが不要になります。