人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

あるディレクトリ以下全て(同一ディレクトリということではなく、ディレクトリ以下で階層は不明)の同じ拡張子のファイル(例えばxxx.html)を一つのファイルに結合する(アプリまたはコマンド)をアドバイスいただけますでしょうか?結合するにあたってファイルの順番は問いません。一つのファイルに格納されれば構いません。

ファイル結合にあたって文字コードが異なっている可能性もあり、その文字コードも統一する前処理作業も必要なことはわかっているのですが、

Windows8又は、Macintoshでできる方法をお教えいただけると。
(プログラムを書けばいいのは分かるのですが、結構例外が多そうなので、まず出来上がったサンプルファイルを作り、評価をしてからプログラミングをしたいと思いまして)

●質問者: owada
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● POGPI
●25ポイント

PHPだとこんな感じですかね。サイズが大きいと、うまく行かないかも知れません。
$data = "";

$files = dir(パス);
while (($filename = $files->read()) != FALSE) {
$filepath = (パス) . "/" . $filename;

$data = $data . file_get_contents($filepath);

}
file_put_contents(パス,$data);


POGPIさんのコメント
Rubyを使えば、ディレクトリ内を再帰的に処理できるようです。 Find.find(パス)で取得できます。

owadaさんのコメント
ありがとうございます。 Rubyが一番良さそうな気がして、Rubyを勉強始めています。 丁度やりたいこと全部を出来ることを紹介している本も見つけました。

2 ● hissssa
●25ポイント ベストアンサー

一回だけの処理なら、単に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
)


ku__ra__geさんのコメント
自分も質問のような作業が必要な場合、この手法を使いますね。 付け加えるなら「dir *.html /s /b | clip」とやると、結果がクリップボードに入るので作業用ファイルが不要になります。

3 ● siachan
●25ポイント

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なるモジュールもあるようですが、試してはいないのでどれほどのものかはわかりません。


owadaさんのコメント
ありがとうございます。 perlがこの手の処理にもっとも向いているのは分かるのですが、なかなか私には敷居が高いですが、最後はここに挑戦してみたいと思います。 勉強になります。ありがとうございました。

4 ● a-kuma3
●25ポイント

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

owadaさんのコメント
ありがとうございます。 こういう方法があったのですね。 スクリプトでほぼ問題解決できるということ、大変勉強になりました。 (自分の不勉強を恥じるとも言いますか・・・)。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ