とまと あんらいぷ…

エンジニアの活動記録とかつぶやきとか

GitHub

カテゴリ:コマンドプロンプト の記事一覧

xcopy ディレクトリ構造も含めてファイルをコピーしたい


ディレクトリ(フォルダ)の中にあるファイルを、
ディレクトリ構造も含めてコピーしたい事は多い。

軽微なファイルであれば、親のディレクトリ毎コピーすれば良いのですが、
以下のように、同じ階層に大きなファイルが転がっている場合はなかなかそんな方法も使えない。

Y:\a\b\c\d\e\FILE1.txt
Y:\a\b\c\d\e\FILE2.txt ←とてつもなくデカイファイル

copyコマンドではできないのでxcopyコマンドを使う



さて、ディレクトリ構造も含めてファイルをコピーしたい場合は
xcopyコマンドを使う必要がでてくる。

オプションパラメータに/Iを付けると、
「 指定されたコピー先が存在せず、コピーするファイルが複数の場合、
コピー先をディレクトリとしてコピーします。」
などという良くわからない説明の代わりに、ディレクトリ構造ごとコピーしてくれます。

期待する結果

【実行コマンド】
xcopy Y:\a\b\c\d\e\FILE1.txt W:\a\b\c\d\e\FILE1.txt /I


【期待する結果】

Y:\a\b\c\d\e\FILE1.txt

W:\a\b\c\d\e\FILE1.txt

がしかし、途中で妙な質問を受ける。


「W:\a\b\c\d\e\FILE1.txt は受け側のファイル名ですか、またはディレクトリ名ですか」
(F= ファイル、D= ディレクトリ)?

【Fを選択した場合の実行結果】

W:\a\b\c\d\e\FILE1.txt

【Dを選択した場合の実行結果】

W:\a\b\c\d\e\FILE1.txt\FILE1.txt

なるほど、確かに「FILE1.txt」というフォルダ名を作成できるので
どちらかハッキリしろよということなのでしょう。

ファイルであると指定する



さて、ファイルをコピーすると分かりきっているのに
毎度毎度 「ファイル名ですか、またはディレクトリ名ですか」と聞かれるのは面倒くさい。
というわけで、パイプ処理を使って予め「F」を入力するようにします。

echo F | xcopy Y:\a\b\c\d\e\FILE1.txt W:\a\b\c\d\e\FILE1.txt /I


echoコマンドで F をパイプで送りつけてやれば、Fを押したことになって、確認を自動的にすっ飛ばしてくれます。

for文でファイルを1つずつ処理する

コマンドプロンプトのfor文でファイルを回す


読者さんからの書き込み質問に回答するかたちで、for文でファイルを1つずつ処理するサンプルバッチを作りました。

せっかくなのでコピペ用としてメモを残しておきます。
てい!

@echo off
setlocal enabledelayedexpansion

cd E:\work
set fileindex=1
for /f %%i in ('dir /b /a-d') do (
echo %%i を %%~ni_!fileindex!%%~xi にリネームします
ren %%i %%~ni_!fileindex!%%~xi
set /a fileindex=fileindex+1
)
pause


このバッチは、フォルダに存在するファイルを全て連番を付けてリネームします。
例えば E:\work ドライブ直下に以下のファイルがあると・・・
A.txt
B.txt
C.txt
D.txt

▼実行後▼
A_1.txt
B_2.txt
C_3.txt
D_4.txt

こんなのになる。
大量のファイルを統一させた命名にリネームする時なんかに便利かもしれない!

バッチファイル内のネットワークパス操作はpushd/popdを使おう

バッチファイルで作業フォルダを指定してexe実行の記事で、
フォルダ移動に「cd」コマンドを利用しました。

しかし、バッチファイルやコマンドライン内で
UNC、つまりネットワークパスが絡んでくる場合は
「pushd/popd」コマンドを使うと便利です。

ネットワークパス(UNC)を扱えないコマンド


「cd」コマンドは、残念ながらUNCを扱うことができません。

例えばこのようなコマンドを打つと・・・・

cd \\192.168.11.5\Users\Public


'\\192.168.11.5\Users\Public'
CMD では UNC パスは現在のディレクトリとしてサポートされません。


う・・・

しかし「pushd」コマンドであれば、UNCを扱うことができます。

pushd \\192.168.11.5\Users\Public

C:\Users\user>pushd \\192.168.11.5\Users\Public

Y:\Public>


ほらね。

pushdコマンドの挙動


pushdコマンドにネットワークパス(UNC)を指定すると、そのネットワークパスに対して
ネットワークドライブを割り当てます。
上述の実行結果が「Y:\Public>」となっているのは
「\\192.168.11.5\Users\Public」にY:\ドライブが割り当てられた事を表していて

エクスプローラーで確認すると、ネットワークドライブが割あたっている事を確認することができます。
20141127_pushd

<h4>popdコマンドで戻る
さて、pushdコマンドと対になっている、popdは、
「元のパスに戻る」という機能を有しています。
実行と同時にネットワークドライブも解除されます。
「元のパスに戻る」は、cdコマンドには無いので便利です。

Y:\Public>popd

C:\Users\user>


このように、ネットワークパス(UNC)をサポートしていないコマンドを利用する場合は
pushdで一旦ネットワークドライブを作成し、あたかもローカルで処理するように見せかけることで
対応できます。

それでは良きコマンドラインライフを!

バッチファイルでFOR文のファイルパスにダブルクオーテーション付きの変数をセットする

FOR文の[セット]にダブルクオート付きのフルパスを入れる



相変わらずのコマンドラインヘルプの不親切ぶりにハマった。
もちろん、ヘルプをよく読んでない私自身のせいなのですが。

今回は変数「hoge」に、ファイルのフルパスをセットして、その内容をFOR文で回す。
という処理を行いたかったのです。

ファイルの内容は
このように改行つきの文字。
a
b
c

以下の様なコマンドを実行した時に期待する動作は・・・

SET hoge="myfile.txt"
FOR /F %%i in ( %hoge% ) do @echo %%i


D:\test>SET A="myfile.txt"
D:\test>FOR /F %i in ("myfile.txt") do @echo %i
a
b
c


こんな感じ。

でも実際には

D:\test>SET A="myfile.txt"
D:\test>FOR /F %i in ("myfile.txt") do @echo %i
myfile.txt


そうじゃない感がすごい(笑)

そもそもダブルクオートを使う必要があるのは
フォルダやファイル名にスペースがある時が多いのですが
恒例的に付けることもありますし、なにより、ファイルパスの内容をぶん回したいのに
ファイルパスそのものがでてくるのは意図していない。

というわけで

[usebackq] オプションを使います。

usebackqオプションを利用してFOR文を実行


FOR /F "usebackq" %i in ("myfile.txt") do @echo %i
実行結果


D:\test>SET A="myfile.txt"
D:\test>FOR /F "usebackq" %i in ("myfile.txt") do @echo %i
a
b
c


この事象にぶち当たった時に変数の展開方法にベクトルを向けてしまうと
%~1 展開時にダブルクオーテーションを除く
に焦点が行ってしまったり。(私だけか・・・)

%~1は引数の展開方法であって、変数の展開方法ではないので、ダブルクオートを除く行為はできません。
お気をつけ下さい。

「フォルダ(ディレクトリ)構造のみコピーする」を送るメニューで便利に実装-xcopy

xcopyを使ってフォルダ構造のみを複製


特定のフォルダ構造を、
中のファイルを除いてコピーしたい時、xcopyコマンドを使えば簡単に実装できます。

コマンドは以下の通り

xcopy コピー元フォルダパス コピー先フォルダパス /t /e

オプションに[/T]と[/E]を指定します。

/T の説明
ファイルはコピーせずにディレクトリ構造のみを作成します。空の
ディレクトリまたはサブディレクトリは除きます。"/T /E" と指定
すると空のディレクトリやサブディレクトリも作成されます。

/E の説明
ディレクトリまたはサブディレクトリが空であってもコピーします。
"/S /E" と同じ意味です。/T の内容を変更する際にも使用できます。

右クリックの「送る」に入れて便利に


毎回コマンドを叩くのが面倒なので
フォルダを右クリック→「送る」
でいつでもフォルダコピーできるようにしたいので
とりあえず、引数に渡されたフォルダ構造のみをデスクトップに保存するバッチを作ります。

コードはこちら


バッチファイルには引数を送ることができ、
ファイルやフォルダをドラッグ&ドロップすると

バッチファイルの中では「%1」が、第一引数となり
ファイルやフォルダが送られてきた時には「%1」にそのパスが格納されています。

SET target=%USERPROFILE%\Desktop\DuplicateFolder

は、デスクトップに「DuplicateFolder」というフォルダを作るための前準備
「%USERPROFILE%」は環境変数といって、
ログインしているユーザーの専用パスが格納されています。

mkdir %target%
でデスクトップにDuplicateFolderフォルダを作成してます。
mkdirは便利な子で、指定したフルパスの途中にあるフォルダが存在しなければついでに作成してくれます。

例:mkdir c:\aaa\bbb\ccc
aaaフォルダが存在しなければ、aaa、bbb、ccc共に全部作ります。働き者ですね。

さて本題のxcopyです。

xcopy %1 %target% /t /e

などと書いてますが、
このファイルに、C:\TESTAをドラッグ&ドロップした場合

%ふにゃふにゃを展開すると

xcopy C:\TESTA C:\Users\tomato\Desktop\DuplicateFolder /t /e

となります。

さて、これを
右クリックの「送る」メニューに入れます。

予定ではこんな感じ。

20140416_xcopy.png

「送るメニューに」ファイルを配置する手順は以下のとおり。

1.Windowsボタン + R ボタンを押してファイル名を指定して実行ウィンドウを開く
2.shell:sendto と打ち込んでエンターキーを押す。

フォルダが開きます。
このフォルダが、送るメニューに入ってるファイル一覧です。

これで、フォルダを右クリックして送るだけで、デスクトップにフォルダ構造だけを複製した
フォルダ一覧が作成できます。

テーマ:プログラミング - ジャンル:コンピュータ

バッチファイルでexeを連続実行する方法


バッチファイルでexeを連続起動


時代に逆行してる気がしますが
前回に引き続き、バッチファイルの話です。

バッチファイルで、何らかのアプリケーションを実行するとき
そのアプリケーションのパスを記載すれば実行できます。

今回は、notepadコマンド、つまりメモ帳をバババ!と開く
コマンドを作ってみました。

20140409_notepad01.png
こんな感じ。

echo メモ帳を3回起動します
notepad
echo 1回目起動!
notepad
echo 2回目起動!
notepad
echo 3回目起動!

途中途中でechoコマンドを使ってコマンドラインに出力します。

というわけで実行

20140409_notepad02.png

・・・1回目起動でとまりました。
Xを押してメモ帳を閉じます。

20140409_notepad03.png

2回目も同じです。

20140409_notepad04.png

20140409_notepad05.png

3回目も同じく、メモ帳が閉じるまで、次のコマンドが動きません。
続きを読む

テーマ:プログラミング - ジャンル:コンピュータ

バッチファイルで作業フォルダを指定してexe実行

作業フォルダとはなにか


exeファイルを実行するとき、「作業フォルダ」というものがあります。
ショートカットを作って、プロパティを開いた時のコレです。

20140408_01work.png

この作業フォルダ、そのファイルを実行する時のルートとなるパスのことで、
例えば

D:\blog\test.bat
というバッチファイルを作って、そのバッチファイルの中で
D:\blog\test.txt を開きたいときは
「test.bat」と「test.txt」が同一フォルダに存在すれば
test.txt って書くだけで開くことができます。

20140408_02work.png

20140408_03work.png

20140408_04work.png

ほらね。

次に、このtest.batのショートカットを、デスクトップに作ってみます。

20140408_05work.png

で、実行

20140408_06work.png

問題なく起動できます。

では、test.batの、ショートカットのプロパティを見てみましょう。

続きを読む

テーマ:プログラミング - ジャンル:コンピュータ

dirコマンドでよく使うパラメータ・オプションまとめ

dirでファイル一覧を取得したい


フォルダの中のファイル数やサイズを確認する時はプロパティを確認すればひと目で分かるのだけど、
ファイル名やフォルダ構成まで確かめようとすると簡単にはいかないし、漏れも出ます。

ファイル確認

プロパティ確認
これじゃあ詳細が分からん。
フォルダ1の中にはフォルダが2個あって、それぞれのフォルダの中にはファイルが2つあるのだよ・・・

・ルートフォルダ(調べている場所)
├/ファイル1
├/ファイル2
├■フォルダ1
 ├/ファイル3
 ├/ファイル4
 ├■フォルダ2
  ├/ファイル5
  └/ファイル6
 └■フォルダ3
  ├/ファイル7
  └/ファイル8
└■フォルダ4
 ├/ファイル9
 ├/ファイル10
 ├■フォルダ5
  ├/ファイル11
  └/ファイル12
 └■フォルダ6
  ├/ファイル13
  └/ファイル14


この構成を出したい。
そこで、コマンドプロンプトでdirコマンドを使ってフォルダやファイル数を出力して
Excelにまとめたりして確かめるのですが
「dir」と単純に打ち込んでもやっぱり簡単にはリスト出力してくれません。
D:\command_dir>dir
ドライブ D のボリューム ラベルは ボリューム です
ボリューム シリアル番号は 82E4-8442 です

D:\command_dir のディレクトリ

2013/08/03 22:27 <DIR> .
2013/08/03 22:27 <DIR> ..
2013/08/03 22:23 6 0001.txt
2013/08/03 22:23 6 0002.txt
2013/08/03 22:27 <DIR> フォルダ1
2013/08/03 22:28 <DIR> フォルダ2
2 個のファイル 12 バイト
4 個のディレクトリ 493,871,255,552 バイトの空き領域

ほらね。

求めてるのはこういう結果です。
D:\command_dir\0001.txt
D:\command_dir\0002.txt
D:\command_dir\フォルダ1\F1_FILE1.txt
D:\command_dir\フォルダ1\F1_FILE2.txt
D:\command_dir\フォルダ1\フォルダ1-1\F1F1_001.txt
D:\command_dir\フォルダ1\フォルダ1-1\F1F1_002.txt
D:\command_dir\フォルダ1\フォルダ1-2\F1F2_001.txt
D:\command_dir\フォルダ1\フォルダ1-2\F1F2_002.txt
D:\command_dir\フォルダ2\F2_FILE1.txt
D:\command_dir\フォルダ2\F2_FILE2.txt
D:\command_dir\フォルダ2\フォルダ2-1\F2F1_001.txt
D:\command_dir\フォルダ2\フォルダ2-1\F2F1_002.txt
D:\command_dir\フォルダ2\フォルダ2-2\F2F2_001.txt
D:\command_dir\フォルダ2\フォルダ2-2\F2F2_002.txt


dirコマンドのヘルプを表示させると、いつものごとく分かりにくい説明が出てきます。
D:\command_dir>dir /?
ディレクトリ中のファイルとサブディレクトリを一覧表示します。

DIR [ドライブ:][パス][ファイル名] [/A[[:]属性]] [/B] [/C] [/D] [/L] [/N]
[/O[[:]ソート順]] [/P] [/Q] [/R] [/S] [/T[[:]タイムフィールド]] [/W] [/X] [/4]


[ドライブ:][パス][ファイル名]
一覧表示するドライブ、ディレクトリ、またはファイルを指定します。

/A 指定された属性のファイルを表示します。
属性 D ディレクトリ R 読み取り専用
H 隠しファイル A アーカイブ
S システム ファイル I 非インデックス対象ファイル
L 再解析ポイント - その属性以外
/B ファイル名のみを表示します (見出しや要約が付きません)。
/C ファイル サイズを桁区切り表示します。これは
既定の設定です。/-C とすると桁区切り表示されません。
/D /W と同じですが、ファイルを列で並べ替えた一覧を表示します。
/L 小文字で表示します。
/N ファイル名を右端に表示する一覧形式を使用します。
/O ファイルを並べ替えて表示します。
ソート順 N 名前順 (アルファベット) S サイズ順 (小さい方から)
E 拡張子順 (アルファベット) D 日時順 (古い方から)
G グループ (ディレクトリから) - 降順
続行するには何かキーを押してください . . .


・・・というわけで
dirコマンドの後ろにくっつけるパラメータ(オプション)
をまとめておきます。 続きを読む

テーマ:プログラミング - ジャンル:コンピュータ

バッチファイルのif文やfor文で気をつけること

if文の中で変数の値が反映されない


バッチスクリプトでハマッた。
if文、for文の中で変数を操作する処理を書いても
予想した通りの結果になりません。

「遅延環境変数の展開」という機能を有効にする必要があるので
注意点をメモしておきます。

作ったバッチファイルは以下


変数[Delay]に1をセットして
if文の中で+1する。

結果は2となっているので
Delay is 1
Delay is 2
final:Delay is 2

が期待する動き。

でも結果は・・・・
Delay is 1
final:Delay is 2

if文の中で2になっているはずなのに判断されてないぞ!?

バッチファイルのif文for文の仕様


if文、for文の中に書いた処理は
「()を抜けてから」変数の値が反映されるようです。
バッチファイルにおいて、コマンドは1行ずつ処理するけど、
if文は括弧()を1行として解釈するみたい。

つまり、ifの中で変数を変更して、その結果を参照するような処理は
書いても無駄ってことだね。

でも、直感的に書きたいよね・・・

遅延環境変数の展開


というわけで直感的に書には、次の2つが必要です。

1.setlocalコマンドにオプション「enabledelayedexpansion」を付ける。
2.変数の展開は「%」ではなくて「!」で行なう。

修正したバッチファイル


結果は・・・・
Delay is 1
Delay is 2
final:Delay is 2

よかった・・・

この解決方法にたどり着くにはifじゃなくて
setlocalのヘルプにヒントが書いてある。


setlocal /?
バッチ ファイルで環境変更のローカル化を開始します。SETLOCAL を実行した後で
変更した環境設定は、そのバッチ ファイルだけで有効です。前の設定を復元するときは
ENDLOCAL を実行しなければなりません。バッチ スクリプトの終わりに達したとき、
暗示的な ENDLOCAL が、そのバッチ スクリプトによって発行されたすべての未完了の
SETLOCAL コマンドのために実行されます。

SETLOCAL

コマンド拡張機能を有効にすると、SETLOCAL は次のように変更されます:

SETLOCAL バッチ コマンドは、オプション引数を受け取ることができます:
ENABLEEXTENSIONS / DISABLEEXTENSIONS
は、コマンド処理機能を有効または無効にできます。これらの
引数は、CMD /E:ON または /E:OFF スイッチよりも優先されます。
詳細については、CMD /? を参照してください。
ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION
は、遅延環境変数の展開を有効または無効にできます。
これらの引数は、CMD /V:ON または /V:OFF スイッチよりも優先します。
詳細については、CMD /? を参照してください。
これらの変更は、SETLOCAL コマンドの実行前の設定にかかわらず、対応する
ENDLOCAL コマンドを実行するまで継続されます。

SETLOCAL コマンドに引数を指定すると、ERRORLEVEL の値が設定されます。


こんなんで分かるわけないです!

テーマ:プログラミング - ジャンル:コンピュータ

バッチファイルでファイル名に連番を付けてコピーする~実行解説

同じファイルに0埋めされた連番を付けてコピーしたい。


テストデータ作成しかり、月次のファイルの作成しかり。

そんなシチュエーションに遭遇した場合
手作業で頑張ってファイルを作るか
ご希望の機能を持つファイラやツールを探すかしないといけない。

ところが昔からあるWindowsの命令言語にはコマンドプロンプトというものがあって、
ものすごく標準装備なのに周りは誰も使ってない。
ちょっとぐらい使いこなせてもいいんじゃないでしょうか。

ということで使いこなせていないコマンドプロンプトを少し勉強しておこうと思い
メモしておきます。

今回やりたいことは以下のとおり

1.複製したいファイルを用意する。
2.用意したファイルに対して、希望した枚数を指定したファイル名に変更し、連番を付加してコピーする。

というわけで、できあがったbatファイルは次の通り。



実行結果は
batファイルと同じフォルダに存在するtxtファイルに
連番を付加してコピーしまくります。

実行後のフォルダ内はこんな感じ。

コピー実行

コピー元のtxtファイルが複数あれば、その分倍増するので
実行には注意して下さい。 続きを読む

テーマ:プログラミング - ジャンル:コンピュータ

FC2Ad