とまと あんらいぷ…

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

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 と打ち込んでエンターキーを押す。

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

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

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

次のページ

FC2Ad