2016-12-13 5 views
1

まず、バッチスクリプトを書く経験はあまりありません。このサイトや他のサイトの助けを借りて、ネットワークに接続されていない複数のPCからファイルをUSBドライブにコピーするスクリプトを書きました。今私はこれらのバックアップフォルダをNASドライブにコピーしたいと思います。 NASドライブG:\はフォルダが含まフォルダ名に二番目のアンダースコアで区切られた部分に基づいて、可変の宛先にフォルダをコピーします。

backup_PC1_data1_dd-mm-yyyy 
backup_PC1_data2_dd-mm-yyyy 
backup_PC2_data1_dd-mm-yyyy 
backup_PC2_data2_dd-mm-yyyy 
... 

ABC_PC1 
ABC_PC2 
... 

は、今私は、フォルダ名に応じてNASドライブにUSBドライブからフォルダをコピーするバックアップフォルダがすべてのように命名されています。例えば

Backup_PC1_data1_tt-mm-yyyyBackup_PC1_data2_tt-mm-yyyyBackup_PC2_data1_tt-mm-yyyyBackup_PC2_data2_tt-mm-yyyyはNASドライブ上のフォルダABC_PC2にコピーする必要があり、NASドライブ上のフォルダABC_PC1にコピーされなければなりません。

USBからNASへのコピープロセスは異なるPCで動作する必要があり、一部のPCには複数のHDDがあるため、USBドライブからcopy2NASスクリプトを開始します。私は、ドライブ文字を取得して開始してソースドライブを設定します。

set drive=%~d0 
set source=%drive% 

私の計画はしてBackup_*というソース内のすべてのフォルダを取得することでした:

for /d %%i in ("%source%\Backup_*") 

、その後の名前を分割するような何かBackup__data…の間の部分を使用して、宛先フォルダ(常にG:\ABC_XXX)を定義します。ここで、XXXは、ソースフォルダ名のBackup__data*の間の部分です。

のようなコードを書く:名前がBackup_*であればUSBドライブチェック上のすべてのフォルダについて

  • はいの場合は、名前を分割してBackup__data*の間で部分を抽出します。
  • ソースフォルダー名の抽出部分を使用して、宛先フォルダーを指定します。
  • 送信元フォルダ(およびその中のファイル)を送信先にコピーします。

私がこれまでにコード化されています:

set drive=%~d0 
set source=%drive% 
for /d %%i in (%source%\Backup_*) do call :ProcessDir "%%i" 

:ProcessDir 
set "foldername=%~n1" 
echo %foldername% 
for /F "tokens=2 delims=_" %%a in ("%foldername%") do set nthstring=%%a 
set "Source=%source%\%foldername%" 
set "destination=C:\mol\backups\backup_nas\GMH_%nthstring%\%foldername%" 
robocopy %Source% %destination% /s 

しかし、これは私のバッチスクリプトのスキルを超えているように見えます。私はどちらもコピープロセスなしで、または新しく作成された宛先へのファイルだけになりました...

Backup_*フォルダはUSBドライブ上の唯一のフォルダではありません。

このタスクをどのように実現するか考えている人はいますか?

+1

あなたが試したことを分かち合い、困ったことを説明してください!ファイルが既に宛先ディレクトリに存在する場合にはどうなりますか?/d/dの代わりに – aschipfl

+1

を使用すると、( 'Dir/B/ADバックアップ_ * _ * _ *^|| findstr' [0-9]でトークン= 1-4delims = _ " [0-9] * - [0-9] [0-9] * - 20 [0-9] [0-9] $ "')エコー#%% A#%% B#%% C#% %D# 'デモだけのエコー。 – LotPings

+0

これまでのところ、私はこれを持っている: '設定ドライブ=%〜D0 集合ソース=%ドライバ% 用/ D %%のI(%ソース%\ BACKUP_ *)を呼び出してください:ProcessDirを "%% I" を:ProcessDir "foldername =%〜n1"を設定します /Fの "%2" %% aの "%foldername%")を設定するには、/% =%ソース%\%フォルダ名%」 セット "宛先= C:\モル\バックアップ\ backup_nas \ GMH_%nthstring%\%フォルダ名%" のRobocopy%出典%の%先%/ S' –

答えて

0

これは、次のバッチコードで実現することができます:外 FORループが非でディレクトリを隠されたバッチファイルのドライブのルートディレクトリにあるためオプション/D(ディレクトリ)の見つけ

@echo off 
for /D %%I in ("%~d0\backup_*_*") do (
    for /F "tokens=2 delims=_" %%J in ("%%~nxI") do (
     echo Copying %%I to G:\ABC_%%J ... 
     %SystemRoot%\System32\xcopy.exe "%%I" "G:\ABC_%%J\%%~nxI\" /C /E /H /I /K /Q /R /Y /Z >nul 
    ) 
) 

backup_で始まり、ディレクトリ名に少なくとも1つ以上のアンダースコアを持つ名前。

ループ変数Iは、完全なパスで見つかったディレクトリ名を二重引用符で囲まずに実行する各ループ上に保持されます。

内側は、バックアップディレクトリの名前だけをダブル引用符で囲んで%%~nxIという文字列で取得します。 %%~nIは、バックスラッシュがない場合は最後のバックスラッシュまたはストリングの開始後の文字列として解釈されます。最後のバックスラッシュの後のポイントがない場合は、最後のポイントまたはストリングの終わりまでは含まれません。拡張子のないファイル。 %%~xIは、最後のバックスラッシュ/文字列の開始からファイル拡張子を意味する文字列の最後までの文字列として解釈されます。したがって、%%~nxIは、解析された文字列中の最後のバックスラッシュ/文字列の開始後の文字列であり、ファイルまたはディレクトリ全体の名前です。ちょうど%%~nIだけでもここのようにディレクトリ名にポイントがないディレクトリで十分でしょう。

FORインナーは理由オプション/Fと最初(内に二重引用符で囲まれた文字列... )ちょうどこの文字列で解析します。したがって、ファイルを検索したり、コマンドラインの出力を解析したり、オプション/Fを使用して可能な限りテキストファイルから行を読み込みません。 2つの二重引用符の間の文字列を解析するだけです。

この文字列は、区切り文字としてデフォルトで使用されるスペース/タブではなく、delims=_で指定された区切り文字としてアンダースコアを使用して複数の文字列に分割されます。

tokens=2で、1つ以上のアンダースコアまたはストリングの終わりの間の2番目の文字列がさらに重要であることが指定されています。

したがって、内部ループ変数Jは、バックアップディレクトリの例に対して、最初のアンダースコアと2番目のアンダースコアの間の文字列を保持します。

これで、USBドライブ上のバックアップフォルダをNASドライブ上の適切なフォルダにコピーするために必要なことがすべて今決定されました。

コマンドXCOPY(Windows XPでも利用可能)コマンドは、すべてのサブフォルダとファイルを含むバックアップフォルダ全体を、存在しない場合でも自動的に作成されるNASドライブ上のフォルダにコピーするために使用されます。

バックアップフォルダの名前も宛先フォルダとして指定することが重要です。それ以外の場合、バックアップフォルダのファイルとサブフォルダはG:\ABC_PCxにコピーされます。

また、宛先フォルダがバックスラッシュで終了することも重要です。XCOPYには、宛先がフォルダではなくファイルであることが分かります。オプション/Iは、末尾にバックスラッシュを付けて宛先を指定する場合には、実際には必要ありません。

また、コピー用DIRバックアップフォルダに設定された隠し属性を持つバックアップディレクトリコマンドを使用する必要がある:

@echo off 
for /F %%I in ('dir /AD /B "%~d0\backup_*_*" 2^>nul') do (
    for /F "tokens=2 delims=_" %%J in ("%%I") do (
     echo Copying %~d0\%%I to G:\ABC_%%J ... 
     %SystemRoot%\System32\xcopy.exe "%~d0\%%I" "G:\ABC_%%J\%%I\" /C /E /H /I /K /Q /R /Y /Z >nul 
    ) 
) 

コマンドDIR返すためのオプション/AD(属性ディレクトリ)ディレクトリだけでマッチングのをバッチファイルのドライブのルートディレクトリのパターンbackup_*_*は、オプションの/Bのため、パスのないディレクトリの名前だけを意味し、二重引用符で囲まれません。ディレクトリには隠し属性が設定されている場合もあります。

外側ためのオプション/F実行され、最初の(内の単一引用符で囲まれた文字列... )実行するためのコマンドラインとしてこの文字列のSTDOUTを処理するには、このコマンドラインで各ラインの出力を処理

ループ変数Iは完全なパスなしでコマンドDIRでわずかバックアップディレクトリ名の出力を保持していることを今に考慮しなければならないことにより、上述したようインナーのために働きます。したがって、バックアップディレクトリ名の参照は、外側のコマンドブロック内のすべての3つのコマンドで少し異なりますの場合

2^>nulは、それを抑制するための装置NULハンドルSTDERR FOR による実行のコマンドDIRによるエラーメッセージの出力をリダイレクトします。バックアップディレクトリが見つからなかった場合は、DIRという紛らわしいエラーメッセージが出力されます。ここで>^にエスケープして、後でこの文字をDIRと解釈し、リダイレクト演算子として解釈し、コマンドラインで間違った位置指定リダイレクション演算子として解釈する必要はありません。 FORで実行するコマンドライン内の2>nulだけを使用すると、構文エラーが原因でバッチ処理が終了します。

使用されているコマンドとその動作方法を理解するには、コマンドプロンプトウィンドウを開き、次のコマンドを実行して、コマンドごとに表示されているすべてのヘルプページをすべてよく読んでください。

  • dir /?
  • echo /?
  • for /?
  • xcopy /?

そしてまた、Microsoftの記事Using command redirection operatorsを参照してください。

+0

私は数日間旅行していますので、今私はただあなたに返信しています。ありがとうございました。コードはまさに私が望むものです。 –

関連する問題