へっぽこヘタレシステム管理者の管理人です。
職場である部署から・・・
ファイルサーバーの全てのフォルダを対象にして・・・
【とあるファイル名】を含むファイルを一括で取得したいという依頼がありました。
ファイルサーバの全てのフォルダですので・・・
かなりのフォルダ数やファイルがあります。
また、場合によっては同じファイル名がイロイロなフォルダに点在していますので・・・
単純にコピーすると上書きされるわけですね。
ファイルのパスを取得する
管理人の職場のファイルサーバには・・・
NECの【NIAS】が導入されています。
NIASとはファイルサーバ統合管理ソフトウエのことです。
このNIASにはファイルの検索機能があり・・・
ファイル名に含まれる文字列から・・・
ファイルサーバ内の全てのファイルを検索し、
該当するファイルのパスを取得することができます。
バッチファイルでコピーしてみる・・・
ファイルのパスが分かれば・・・
あとはバッチファイルで一括コピーを試みます。
単純に吐き出されたCSVファイルのテキストを成形して・・・
次のバッチファイルを作りました・・・
例ではローカルドライブの【D:¥WORK】にコピーします。
copy ファイルのパス名 d:\work
copy ファイルのパス名 d:\work
copy ファイルのパス名 d:\work
copy ファイルのパス名 d:\work
copy ファイルのパス名 d:\work
copy ファイルのパス名 d:\work
・・・・
ファイルサーバに該当のファイルが何個あろと・・・
これでコピーはできるのですが・・・
いろんなフォルダからファイルを取得するので・・・
同じファイル名が結構あって勝手に上書きされるので全ての取得ができません。
そこでファイル名に連番を付けながらコピーする方法をバッチファイルで考えてみました。
set
今回のテストでやりたいことは次のとおりです。
- ローカルドライブの【E:\work\test1】にファイルを5作っておく
- ローカルドライブの【E:\work\test2】にファイル名を変更してコピーする
まずは【SET】で変数にファイルパスを指定してみます。
ファイルの数はかなりありますが・・・
setでの変数設定はエクセルとテキストエディタでできますので・・・
とりあえず変数の宣言をしておきます。
次のコードでこれが正しく出力されるか確認します。
@echo off
set file1=E:\WORK\test1\111.txt
set file2=E:\WORK\test1\222.txt
set file3=E:\WORK\test1\333.txt
set file4=E:\WORK\test1\444.txt
set file5=E:\WORK\test1\555.txt
echo %file1%
echo %file2%
echo %file3%
echo %file4%
echo %file5%
上のコードを実行するとしたの結果が取得されます。
ファイルがフルパスで出力されます。
E:\WORK>test2.bat
E:\WORK\test1\111.txt
E:\WORK\test1\222.txt
E:\WORK\test1\333.txt
E:\WORK\test1\444.txt
E:\WORK\test1\555.txt
E:\WORK>
for で繰り返す
COPYの行を全て手打ちする訳にはいかないので【for】を使って繰り返します。
【for】文を使ってファイル名の取得を試みます・・・
コードは次のとおりです。
@echo off
set file1=E:\WORK\test1\111.txt
set file2=E:\WORK\test1\222.txt
set file3=E:\WORK\test1\333.txt
set file4=E:\WORK\test1\444.txt
set file5=E:\WORK\test1\555.txt
for /l %%n in (1,1,5) do (
set fname=file%%n
echo %fname%
)
実行すると上手くいきません。
E:\WORK>test2.bat
file5
file5
file5
file5
file5
上手くいかないので普通に【for】文を実行してみます。
@echo off
for /l %%n in (1,1,10) do (
echo %%n
)
これだったらうまいく行きます・・・
【SET】とつなげると上手くいかないようです。
E:\WORK>test3.bat
1
2
3
4
5
6
7
8
9
10
setlocal enabledelayedexpansion
どうも調べてみるとバッチファイルの変数は・・・
上から順番ではなく・・・
最初に読み込まれた時に値に置き換わるそうです・・・
これを順番に変数の変更していくには・・・
【setlocal enabledelayedexpansion】を宣言し・・・
変数を読み込むときの変数指定を【%変数名%】から、
【!変数名!】に変更します。
これを【遅延環境変数】と言います。
@echo off
setlocal enabledelayedexpansion
set file1=E:\WORK\test1\111.txt
set file2=E:\WORK\test1\222.txt
set file3=E:\WORK\test1\333.txt
set file4=E:\WORK\test1\444.txt
set file5=E:\WORK\test1\555.txt
for /l %%n in (1,1,5) do (
set fname=!file%%n!
echo !fname!
)
endlocal
遅延環境変数に変更して実行すると次のように変数の中味が置き換わります。
E:\WORK>test2.bat
E:\WORK\test1\111.txt
E:\WORK\test1\222.txt
E:\WORK\test1\333.txt
E:\WORK\test1\444.txt
E:\WORK\test1\555.txt
COPY でコピーする
あとは・・・
【COPY】を仕込むだけですが・・・
@echo off
setlocal enabledelayedexpansion
set file1=E:\WORK\test1\111.txt
set file2=E:\WORK\test1\222.txt
set file3=E:\WORK\test1\333.txt
set file4=E:\WORK\test1\444.txt
set file5=E:\WORK\test1\555.txt
for /l %%n in (1,1,5) do (
set fname=!file%%n!
copy !fname! e:\work\test2
)
endlocal
E:\WORK>test2.bat
1 個のファイルをコピーしました。
1 個のファイルをコピーしました。
1 個のファイルをコピーしました。
1 個のファイルをコピーしました。
1 個のファイルをコピーしました。
これでは・・・
同じファイル名があった場合に・・・
上書きされてしまいますので・・・
コピーと同時にファイル名を変更する必要があります。
ファイル名を変更する
ということでファイル名を変更することにします。
変更の方法は・・・
ファイルのフルパスの後ろから数文字を切り取って・・・
頭に連番を付けるというものです。
コピー先のディレクトリを【set】で変数指定し・・・
set fname=!file%%n!
でコピー元のファイルのフルパスを取得します。
set fname2=!fname:~-6!
で、取得したファイルのフルパスの後ろから6文字を取得します。
set fname3=!dirname!%%n-!fname2!
で、コピー先のディレクトリ&連番&コピー元ファイルの後ろから6文字を取得します。
@echo off
setlocal enabledelayedexpansion
set file1=E:\WORK\test1\111.txt
set file2=E:\WORK\test1\222.txt
set file3=E:\WORK\test1\333.txt
set file4=E:\WORK\test1\444.txt
set file5=E:\WORK\test1\555.txt
set dirname=E:\WORK\test2\
for /l %%n in (1, 1, 5) do (
set fname=!file%%n!
set fname2=!fname:~-6!
set fname3=!dirname!%%n-!fname2!
echo !fname!
echo !fname2!
echo !fname3!
)
endlocal
これを実行すると・・・
ファイル名が変更されているのが分かります。
E:\WORK>test4.bat
E:\WORK\test1\111.txt
11.txt
E:\WORK\test2\1-11.txt
E:\WORK\test1\222.txt
22.txt
E:\WORK\test2\2-22.txt
E:\WORK\test1\333.txt
33.txt
E:\WORK\test2\3-33.txt
E:\WORK\test1\444.txt
44.txt
E:\WORK\test2\4-44.txt
E:\WORK\test1\555.txt
55.txt
E:\WORK\test2\5-55.txt
再度 COPY でファイルをコピーする
ようやくこれでファイルのコピーができます。
次のコードを実行すると・・・
@echo off
setlocal enabledelayedexpansion
set file1=E:\WORK\test1\111.txt
set file2=E:\WORK\test1\222.txt
set file3=E:\WORK\test1\333.txt
set file4=E:\WORK\test1\444.txt
set file5=E:\WORK\test1\555.txt
set dirname=E:\WORK\test2\
for /l %%n in (1, 1, 5) do (
set fname=!file%%n!
set fname2=!fname:~-6!
set fname3=!dirname!%%n-!fname2!
echo !fname!
echo !fname2!
echo !fname3!
copy !fname! !fname3!
)
endlocal
コピー先のフォルダにファイル名が変更されたファイルがコピーされます。
フォルダを確認するとしっかりとファイルが保存されていました。
E:\WORK>test5.bat
E:\WORK\test1\111.txt
11.txt
E:\WORK\test2\1-11.txt
1 個のファイルをコピーしました。
E:\WORK\test1\222.txt
22.txt
E:\WORK\test2\2-22.txt
1 個のファイルをコピーしました。
E:\WORK\test1\333.txt
33.txt
E:\WORK\test2\3-33.txt
1 個のファイルをコピーしました。
E:\WORK\test1\444.txt
44.txt
E:\WORK\test2\4-44.txt
1 個のファイルをコピーしました。
E:\WORK\test1\555.txt
55.txt
E:\WORK\test2\5-55.txt
1 個のファイルをコピーしました。
単純な作業ですが・・・
このコードを作るのに半日掛かりました・・・
ファイル数にもよりもすが・・・
手作業でコピーした方が早かったかもです・・・
コメント