2016-12-08 3 views
0

質問と問題を長時間蓄積して解説してください。完全な質問を最初に見るには、以下のヘッダーを参照してください。複数のディレクトリにあるファイルを数える

私が書いているバッチファイルは、特定のファイルを自動的に移動するためのものです。基本的には、インターネットに接続されたネットワークと内部ネットワークで隔離された2つのネットワークがある場所を設定しています。これらの2つのネットワーク間でファイルを移動するには、ユーザーはサーバー上の自分専用のフォルダーにファイルを置いて、そのファイルを外部ドライブにプルして別のネットワーク上のマシンに物理的に移動させ、他のネットワークはありません。ここで

は、フォルダのレイアウトとFolder Structure and Process

を移動するプロセスここでファイルを移動するバッチファイル(関連部分は)だの安っぽい絵です。このスクリプトは、フォルダ間でファイルを移動するだけでなく、移動を待っていたすべてのファイルのログも生成します。

@echo off 

rem Copies the contents of the external drive to the "AlreadyMoved" folders 
dir /b /s /a:d "\\SERVER\Path\Users\*AlreadyMoved" | for /f "delims=\; tokens=3,4,5*" %%a in ('findstr AlreadyMoved') do @xcopy /i /s /y "E:\%%b" "\\SERVER\Path\%%a\%%b\%%c\"  

set folder="E:\" 
cd /d %folder% 

IF EXIST "E:\" (
goto :DRIVECLEAN 
) ELSE (
echo ERROR: "%folder%" DRIVE NOT CONNECTED! 
echo(
echo(
echo PLEASE CONNECT %folder% DRIVE AND TRY AGAIN. 
exit /b) 

:DRIVECLEAN 
set folder="E:\" 
rem echo This will wipe the %folder% drive clean! 
cd /d %folder% 
for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q || del "%%i" /s/q) 

rem gets the current date and time in 24 hr format for the text file name. 
set hh=%time:~-11,2% 
set /a hh=%hh%+100 
set hh=%hh:~1% 
set dateseed=%date:~10,4%_%date:~4,2%_%date:~7,2%_%hh%%time:~3,2% 

set output="%userprofile%\Desktop\Folder\%dateseed%.txt" 

rem creates contents of the log file 
echo File Header >> %output% 
echo(>> %output% 
echo Scanned By: %username% >> %output% 
echo Date Scanned: %mydate% >> %output% 
echo Time Scanned: %mytime% >> %output% 
echo(>> %output% 

rem echoes the File Name, Size, and Last Modified date in the log file 
for /f "delims=" %%F in (
    'dir /b /s \\SERVER\Path\Users ^| findstr ToBeMoved\' 
) do for /f "delims=\; tokens=3,4,5*" %%a in ("%%F") do echo %%b: %%d -- Size: %%~zF bytes -- Last Modified: %%~tF >> %output% 

rem copies the contents of the "ToBeMoved" folders to the External Drive 
dir /b /s /a:d "\\SERVER\Path\Users\*ToBeMoved" | for /f "delims=\; tokens=3,4,5*" %%a in ('findstr ToBeMoved') do @xcopy /i /s /y "\\SERVER\Path\%%a\%%b\%%c" "E:\%%b\" 

pause 

このすべては、このようになりますログファイルに結果:

File Header 

Scanned By: username 
Date Scanned: 12-08-2016 
Time Scanned: 01:03 PM 

Last, First1: FileName1.ext -- 10000 bytes -- Last Modified: 12/08/16 2:50 PM 
Last, First1: FileName2.ext -- 10000 bytes -- Last Modified: 12/08/16 2:55 PM 
Last, First2: FileName3.ext -- 10000 bytes -- Last Modified: 12/08/16 2:50 PM 
Last, First2: FileName4.ext -- 10000 bytes -- Last Modified: 12/08/16 2:55 PM 

質問はここから始まります!

それで、非常に長い風が吹き荒れた後、ここに質問があります。

私はこのように見えるように、テキストファイルを取得したい:

File Header 

Moved By: username 
Date Moved: 12-08-2016 
Time Moved: 01:03 PM 

Last, First1 
FileName1.ext -- 9 KB -- Last Modified: 12/08/16 2:50 PM 
FileName2.ext -- 9 KB -- Last Modified: 12/08/16 2:55 PM 
Total Moved: 2 Files 

Last, First2 
FileName3.ext -- 9 KB -- Last Modified: 12/08/16 2:50 PM 
FileName4.ext -- 9 KB -- Last Modified: 12/08/16 2:55 PM 
FileName4.ext -- 9 KB -- Last Modified: 12/08/16 2:56 PM 
Total Moved: 3 Files 

あなたはこの1と前回のテキストファイルといくつかの違いが、私がしようとしている重要な違いがありますわかります特定のユーザーの "ToBeMoved"フォルダー内のファイル数を数える方法です。

バッチで明白なカウント機能がないことに気付きましたが、ディレクトリ内のファイル数をカウントする方法がいくつか見つかりましたが、これらのスクリプトを実際に実装する方法がわかりません。爆破する

明らかな解決策は、ログファイルの内容を出力する同じループ内でカウントを実装することです。それ以外の場合、私はどのように私はすべてのユーザーの情報を一緒に保持するか分からない。つまり、私が持っているループはすでに私を一緒に束ねるために私を永遠に連れてきました(私はバッチの専門家ではありません)。そして、私はこれらのループに複雑な追加を加える方法をあわてていません。

というボーナスが追加されています(これはこの質問の対象とは完全には関係ありませんが、これらの問題について誰かが助けてもらえない場合は反対しません)。それを理解していないと、私はおそらく別々の質問をしなければならないでしょう)私はサイズの値のいくつかの変換を行い、改行を加えることができる必要があります。

私はこれをどのように達成できるか考えてもらえますか?または、少なくとも正しい方向に私を向ける?

EDIT:これはelzooilogicoの回答に対応しています。私は彼が提案した変更を実装し、コードはエラーなしで実行されましたが、テキストファイルは正しくフォーマットされていません。いくつかのフォルダにいくつかのテストファイルを置いて、何が起こるべきか見てみましょう。

私はこのような何か得ている必要があります。彼は書いたループは、上記の間違いであるため、今では私が何とか間違ってそれを実現している可能性があり

File Header 

Moved By: username 
Date Moved: 12-09-2016 
Time Moved: 10:30 AM 

Last,First1 
Last,First1 
Last,First1 
Last,First1 
Last,First2 
Last,First2 
Last,First2 
FileName1.ext -- Size: 103 bytes -- Last Modified: 12/09/2016 10:25 AM 
FileName2.ext -- Size: 463 bytes -- Last Modified: 12/09/2016 09:28 AM 
FileName3.ext -- Size: 463 bytes -- Last Modified: 12/09/2016 09:29 AM 
FileName4.ext -- Size: 531 bytes -- Last Modified: 12/09/2016 09:31 AM 
FileName5.ext -- Size: 531 bytes -- Last Modified: 12/09/2016 09:31 AM 
FileName6.ext -- Size: 527 bytes -- Last Modified: 12/09/2016 09:37 AM 
FileName7.ext -- Size: 527 bytes -- Last Modified: 12/09/2016 09:42 AM 

:代わりに、それはこのように見えた

File Header 

Moved By: username 
Date Moved: 12-09-2016 
Time Moved: 10:30 AM 

Last,First1 
FileName1.ext -- Size: 1 KB -- Last Modified: 12/09/2016 10:25 AM 
FileName2.ext -- Size: 1 KB -- Last Modified: 12/09/2016 09:28 AM 
FileName3.ext -- Size: 1 KB -- Last Modified: 12/09/2016 09:29 AM 
FileName4.ext -- Size: 1 KB -- Last Modified: 12/09/2016 09:31 AM 
Total Moved: 4 Files 

Last,First2 
FileName5.ext -- Size: 1 KB -- Last Modified: 12/09/2016 09:31 AM 
FileName6.ext -- Size: 1 KB -- Last Modified: 12/09/2016 09:37 AM 
FileName7.ext -- Size: 1 KB -- Last Modified: 12/09/2016 09:42 AM 
Total Moved: 3 Files 

を私のスキルレベル。しかし私はそれを自分のコードに直接コピーし、必要に応じて一般的なビットを修正しました。

最終編集:これは完璧に機能するため、最初は間違っていたはずです。バッチ・ロジックがうまく動作した場合

答えて

1

をテストしていない、

>>"%output%" (
    for ... do (
    echo(... 
    echo(... 
    ) 
) 

は一度だけファイルを開きますこと

rem creates contents of the log file 
>>"%output%" (
    echo(File Header 
    echo(
    echo(Scanned By: %username% 
    echo(Date Scanned: %mydate% 
    echo(Time Scanned: %mytime% 
    echo(
) 

setlocal EnableDelayedExpansion 
set "footer=" 
set "current=" 
set/a counter=0 

rem echoes the File Name, Size, and Last Modified date in the log file 
>>"%output%" (
    for /f "delims=" %%F in (
    'dir /b /s \\SERVER\Path\Users ^| findstr ToBeMoved\' 
) do (
    for /f "delims=\; tokens=3,4,5*" %%a in ("%%F") do (
     if "!current!" neq "%%b" (
     set "current=%%b" 
     if defined footer echo(Total Moved: !counter! Files & echo(
     set/a counter=0, footer=1 
     echo(
     echo(%%b 
    ) 
     set/a counter+=1, size=%%~zF, kbSize=size/1024 
     echo %%d -- Size: !kbSize! Kb -- Last Modified: %%~tF 
    ) 
) 
    if defined footer echo(Total Moved: !counter! Files 
) 
EndLocal 

rem copies the contents of the "ToBeMoved" folders to the External Drive 
dir /b /s /a:d "\\SERVER\Path\Users\*ToBeMoved" | for /f "delims=\; tokens=3,4,5*" %%a in ('findstr ToBeMoved') do @xcopy /i /s /y "\\SERVER\Path\%%a\%%b\%%c" "E:\%%b\" 

pause 

ノートにrem creates contents of the log fileラインから変更してみてください、一方、

for ... do (
    echo(...>>"%output%" 
    echo(...>>"%output%" 
    ) 

>>"%output%"リダイレクトが使用されるたびにファイルを開いて閉じるので、最初にブロックをスピードアップします。

EDIT:簡単な説明

ところで

>>"%output%" (
    for ... do (
    echo(... 
    echo(... 
    ) 
) 

(
    for ... do (
    echo(... 
    echo(... 
    ) 
)>>"%output%" 

EXPLANATIONと同じである

最初に、上記のように1回の開閉サイクルでヘッダーが出力ファイルにエコーされます。

は覚えておいてください:コマンドプロセッサは、ブロック( 括弧の間に何かを)見つけ、それを完全に解析し、ブロックが評価されたときに、彼らが持っている価値 に変数を展開するとき。ブロック内の変数値 を更新する場合は、変数 の遅延拡張を有効にして、変更を反映させる必要があります。 How does the Windows Command Interpreter (CMD.EXE) parse scripts?だから、

上の素敵な説明があります、我々はブロック内で更新された変数を使用しようとしているためsetlocal EnableDelayedExpansionで遅延拡張モードに入り、これは我々が遅延拡張を行うことが%var%から!var!に変数展開構文を変更する必要があります意味します働く

setlocal EnableDelayedExpansion 
set "footer=" 
set "current=" 
set/a counter=0 

fotter and currentは未定義です。

for /f "delims=" %%F in (...) do (
    for /f "delims=\; tokens=3,4,5*" %%a in ("%%F") do (
    if "!current!" neq "%%b" (
     set "current=%%b" 
     if defined footer echo(Total Moved: !counter! Files & echo(
     set/a counter=0, footer=1 
     echo(
     echo(%%b 
    ) 
    set/a counter+=1, size=%%~zF, kbSize=size/1024 
    echo %%d -- Size: !kbSize! Kb -- Last Modified: %%~tF 
) 
) 
if defined footer echo(Total Moved: !counter! Files 

、今、私たちは、メインforループに入るために準備された第2のコンテンツを持つcurrent VARのifテスト内容それはset "fotter="set "current="の目的だと私たちはcounter

0に初期化第2の forループによって与えられるトークン。このブロックは、現在の変更があったときにのみ実行され、未定義であることを覚えているので、最初の時間も実行されます。 footerプリントフッターを定義した場合には、その値を変更するたびにトークンが変更されたことを意味し と

  1. 我々は、現在の
  2. の値を更新(この場合には、そのフォルダの変更である)(コンテンツカウンターの)。再び初めてfooterが定義されていないので、フッターは印刷されません。
  3. 次に、カウンタがリセットされ、footerが定義されます。次回に印刷されます。
  4. フォルダの名前が印刷されます。

ifブロックラインは、すべてfor反復

  1. 最初の行が実行された後、カウンタを更新し、ファイルサイズを取るkbのサイズを計算します。
  2. 秒1、出力ファイルに現在のアクションの情報をフラッシュ

最後if defined footer echo(Total Moved: !counter! Filesかのブロックが最後forを実行されませんようforブロックは、最後のフッタが印刷されることを保証した後、フッターなしで最後のフォルダーの内容を残します。

希望すると助かります!

NEW EDIT:あなたのcomparisionsがケースでない場合

ところで、あなたはif /I "!current!" neq "%%b"代わりのif "!current!" neq "%%b"(大文字と小文字を区別)オーケー

+0

を使用することができsentitive ...私は夜に多くのコーヒーが必要だと思いますこれはすばらしく、私のスキルレベルをはるかに上回っています。うまくいけば、単にそれを実装していないだけです。 私は、ユーザ名、ファイル名、サイズ、および変更日を追加したビットで生成する元のコードブロックを置き換えました。しかし、それは間違いなく実行されましたが、私が試していたものを得られませんでした。出力する内容を編集します。 また、変更したビットは、出力が1回だけ書き込まれるのが大好きです。私はあなたがそれを行うことができるのか分からず、ここからその方法を間違いなく使用するつもりです。 – Neal

+0

はコンピュータの前にはありませんが、前のスクリプトが正常に実行されている場合は、これがジョブを実行するはずです。変更されたコードブロックの前に*エコーを置くことをお勧めします。* rem *リダイレクションラインと終了マッチング括弧は、forの中にポーズを入れます。* for * iterationごとに何が起こっているか見ることができます。 – elzooilogico

+0

もう一度入れてみました。今は完璧に動作するので、何かを混乱させてしまったに違いない!ありがとうございました!あなたは基本的にバッチイエスです。 – Neal

関連する問題