2016-10-28 5 views
1

私のコードでは、フォルダ内のファイルとすべてのサブフォルダのみを検索しています。サブフォルダの名前がの空白の場合は、このサブフォルダの間の空白は(スペース)です。このサブフォルダもファイルとして認識されます。これは正しい動作ではありません。パラメータ/a-dはここでは役に立ちません。バッチスクリプトの実行時に、スペースを含むサブフォルダがファイルとして認識されるのはなぜですか?

@echo on 
Setlocal EnableDelayedExpansion 

set "input=C:\Users\NekhayenkoO\test\"** 
set "output=C:\Users\NekhayenkoO\outputxml\"** 

set string1=Well-Formed and valid 
set string2=Well-Formed, but not valid 
set string3=Not well-formed 
set /a loop=0 
set /a loop1=0 
set /a loop2=0 
set /a loop3=0 

for /f %%a in ('dir /b /a-d /s %input%') do (
    CALL jhove -m PDF-hul -h xml -o %output%\%%~na.xml %%a 
    if !ERRORLEVEL! EQU 0 (echo Errorlevel equals !errorlevel!) 
    if !ERRORLEVEL! GEQ 1 (Errorlevel equals !errorlevel!) 
    set /a loop3+=1 
) 

ディレクトリC:\Users\NekhayenkoO\jhove-betaで実行中のスクリプトの出力:

Setlocal EnableDelayedExpansion 
set "input=C:\Users\NekhayenkoO\test\"** 
set "output=C:\Users\NekhayenkoO\outputxml\"** 
set string1=Well-Formed and valid 
set string2=Well-Formed, but not valid 
set string3=Not well-formed 
set /a loop=0 
set /a loop1=0 
set /a loop2=0 
set /a loop3=0 
for /F %a in ('dir /b /a-d /s "C:\Users\NekhayenkoO\test\"') do (
echo Verarbeite %~na 
CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\%~na.xml" "%a" 
if !ERRORLEVEL! EQU 0 (echo Errorlevel equals !errorlevel!) 
if !ERRORLEVEL! GEQ 1 (Errorlevel equals !errorlevel!) 
set /a loop3+=1 
) 

(
echo Verarbeite 757419577 
CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\757419577.xml" "C:\Users\NekhayenkoO\test\757419577.pdf" 
if !ERRORLEVEL! EQU 0 (echo Errorlevel equals !errorlevel!) 
if !ERRORLEVEL! GEQ 1 (Errorlevel equals !errorlevel!) 
set /a loop3+=1 
) 
Verarbeite 757419577 
Errorlevel equals 0 
Verarbeite GBV58575165X 
Errorlevel equals 0 
Verarbeite GBV85882115X 
java.lang.ClassCastException: edu.harvard.hul.ois.jhove.module.pdf.PdfSimpleObject cannot be cast to edu.harvard.hul.ois.jhove.module.pdf.PdfDictiona 
     at edu.harvard.hul.ois.jhove.module.PdfModule.readDocCatalogDict(PdfModule.java:1344) 
     at edu.harvard.hul.ois.jhove.module.PdfModule.parse(PdfModule.java:521) 
     at edu.harvard.hul.ois.jhove.JhoveBase.processFile(JhoveBase.java:803) 
     at edu.harvard.hul.ois.jhove.JhoveBase.process(JhoveBase.java:588) 
     at edu.harvard.hul.ois.jhove.JhoveBase.dispatch(JhoveBase.java:455) 
     at Jhove.main(Jhove.java:292) 
Errorlevel equals 0 
Verarbeite GBV858852357 
Errorlevel equals 0 
Verarbeite nicht_valide_PDF 
Errorlevel equals 0 
Verarbeite not_Wellformed_intern 
Errorlevel equals 0 
Verarbeite pp1788_text 
Errorlevel equals 0 
Verarbeite Rosetta_Testdatei 
Errorlevel equals 0 
Verarbeite script 
Errorlevel equals 0 
Verarbeite java 
Errorlevel equals 0 
Verarbeite java 
Errorlevel equals 0 
Verarbeite java 
Errorlevel equals 0 
Verarbeite java 
Errorlevel equals 0 
Verarbeite GBV58525785X 
Errorlevel equals 0 
Verarbeite GBV58574517X 
Errorlevel equals 0 
Drücken Sie eine beliebige Taste . . . 
+2

は、引用符を使用around: '... in( 'dir/b/a -d/s "%input%" ')do ... '' CALL jhove -m PDF-hul -h xml -o "%出力%\ %%〜na.xml" "%% a" ' – Stephan

+0

@ステファン私はすでにそれを試しましたが、それは同じ結果です –

+0

@OlegNekhayenko、私はそれが信じがたいことがわかります。私はスクリプトの実行を見たいです。エコーを維持し、その情報であなたの質問を更新してください。 – Squashman

答えて

1

jhoveは何?

Oleg Nekhayenkoの質問には、最終的にはjhoveにいくつか質問がありましたが、あなたの質問すべてについて知っておくことが重要であることを常に忘れています。

したがって、私はすぐにそのdocumentationcommand-line interface説明し、最終的にJHOVEのSourceForgeのプロジェクトページからもダウンロードjhove-1_11.zipを読んで、非常に迅速にホームページ
JHOVE | JSTOR/Harvard Object Validation Environmentjhoveのためにワールドワイドウェブで見つけ検索しました。

このすべてがjhoveは、それが簡単にユーザーが使用することを行うためのバッチファイルjhove.batをシェルスクリプトjhoveを使用し、Windows上でMac上でも、おそらくLinux上で実行されるJavaアプリケーションであることを見つけるために私によって行われました。

あなたがjhove.batを書かれただけではなくjhoveあなたのコードスニペット内または少なくともどこでもjhoveは、バッチファイルであることを言及していた場合は、自分自身と自分の質問のすべての読者に多くの時間を保存している可能性があります。私にはわからない

set "input=C:\Users\NekhayenkoO\test\"** 
set "output=C:\Users\NekhayenkoO\outputxml\"** 

:私は最初
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
の答えとの2行の次の外観を読むことをお勧め環境変数

に値/文字列を割り当てる

なぜ2つのアスタリスクがその2つのコマンドラインの最後にあるのか。しかし、2つの環境変数に2つのパスを割り当てる際には、アスタリスクは両方とも無視されるため、これは問題ではありません。行にはアスタリスク出力がないよう

これは、バッチファイルの掲載出力で見ることができます。

for /F %a in ('dir /b /a-d /s "C:\Users\NekhayenkoO\test\"') do (

CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\757419577.xml" "C:\Users\NekhayenkoO\test\757419577.pdf" 

どこにもアスタリスクはありません。したがって、環境変数inputoutputは明らかにここで良いことである最後のアスタリスクなしで定義されています。

二重引用符でディレクトリとファイル名を囲む

コマンドプロンプトウィンドウで cmd /?を実行しているのヘルプ出力は、ディレクトリやファイル名を二重引用符内の文字の周りに使用する必要のある最後のヘルプページの最後の段落で説明し

完全なディレクトリ/ファイル名。

スペース文字は、コマンドラインで文字を区切る文字であるため、スペースを含むディレクトリまたはファイル名は必ず二重引用符で囲む必要があります。 Windowsの

事前定義された環境変数、コマンドプロンプトウィンドウを開き、またUSERNAMEUSERPROFILEなどPATHPATHEXTを含む現在のユーザーアカウントに対して定義されたすべての環境変数の出力にset結果を実行しています。

についてウィキペディアの記事Windows Environment Variablesは、Windowsによって事前定義された環境変数について説明しています。バッチファイルでそれらを使用することをお勧めします。 Windowsの

上のアプリケーションとスクリプトの

実行ファイル拡張子なしとパスせずにアプリケーションやスクリプトのファイル名のみが指定されているコマンドプロンプトウィンドウまたはバッチファイルでの場合は、Windowsのコマンド・インタプリタが検索されます指定された名前のファイルが環境変数PATHEXTにリストされているファイルの場合は、環境変数PATHのすべてのディレクトリの最初のカレントディレクトリと次のディレクトリにあります。この場合、Windowsコマンドインタープリタはjhove.*を検索しています。環境変数PATHPATHEXT

値は、コマンドプロンプトウィンドウを開き、その現在の値で大文字と小文字を区別しない解釈ストリングPATHで始まるすべての環境変数の出力をもたらすこのウィンドウset pathで実行で見ることができます。

次に、Windowsコマンドインタープリタがjhove.*を検索すると、NTFSファイルシステムはこの検索パターンに一致するファイル名をアルファベット順に返します。したがって、現在のディレクトリまたはPATHに記載されているディレクトリのいずれかがたとえばjhove.batおよびjhove.exeの場合、NTFSファイルシステムは最初にjhove.batを返します。このバッチファイルは、Windowsコマンドインタープリタによって、ファイル拡張子BATがデフォルトでPATHEXTにリストされているために使用されます。

jhove.*ファイルのドライブのファイルシステムがFAT、FAT32またはExFatの場合、ファイルシステムはファイル割り当てテーブルに格納されている順序で検索パターンに一致するファイル名を返します。したがって、ソートされません。したがって、FATファイルシステムを持つドライブにディレクトリjhove.batjhove.exeが含まれている場合、Windowsコマンドインタープリタによって実行されるファイルは、バッチファイルでjhoveと指定すると予測できません。

このため、アプリケーションまたはスクリプトをファイル名と少なくともファイル拡張子で指定することを常にお勧めします。可能であれば、実行するアプリケーションへのパスまたは呼び出すスクリプトも指定する必要があります。

Windowsコマンドインタープリタは、ファイル拡張子が完全なパスのアプリケーションまたはスクリプトファイルの名前を指定して検索する必要はありません。

も参照コマンドブロックが(で始まることにより、ラインによって、Windowsのコマンド・インタプリタラインによって解釈スクリプト(テキストファイル)でアプリケーション

バッチファイルを実行している対バッチファイルを呼び出すWhere is "START" searching for executables?

に答えます一致して終了すると)は1行で定義されたサブルーチンのように解釈されます。

アプリケーションは、特定のプロセッサまたはプロセッサフ​​ァミリ用にコンパイラでコンパイルされた実行可能ファイル(バイナリファイル)であるため、実行時にこれ以上解釈する必要はありません。すでにプロセッサーの命令(マシンコード)が入っています。

は、バッチファイル内から別のバッチファイルを実行するために使用されなければならないコマンドコールがために

に答えて詳細に説明されている理由その理由は、jhoveが何であるかを知ることは非常に重要です。これは、バッチファイルであるため、コマンドプロンプトウィンドウを開き、call /?を実行コマンドコールのヘルプについて質問How to process 2 for loops after each other in batch?

に答えるコマンドコールで呼び出さなければなりません。出力ヘルプは、バッチファイルの引数を参照するプレースホルダも存在し、引き数0はバッチファイルの名前です。

jhove.batを含むコマンドラインはどれですか?

別のバッチファイルからバッチファイルを呼び出す際に予期しない動作が発生すると、バッチファイルと呼ばれるコード内にエラーが存在する可能性があるため、呼び出されたバッチファイルのコードも知っておくことが重要です。

命令コメントなしjhove-1_11.zipに保存されているようjhove.batのコード:

@ECHO OFF 
SET JHOVE_HOME=%~dp0 

SET EXTRA_JARS= 

REM NOTE: Nothing below this line should be edited 
REM ######################################################################### 


SET CP=%JHOVE_HOME%\bin\JhoveApp.jar 
IF "%EXTRA_JARS%"=="" GOTO FI 
    SET CP=%CP%:%EXTRA_JARS 
:FI 

REM Retrieve a copy of all command line arguments to pass to the application 

SET ARGS= 
:WHILE 
IF %1x==x GOTO LOOP 
    SET ARGS=%ARGS% %1 
    SHIFT 
    GOTO WHILE 
:LOOP 


REM Set the CLASSPATH and invoke the Java loader 
java -classpath %CP% Jhove %ARGS% 

まあ、これはその理由を次のように良くない書かれたバッチコードです:

  1. コマンドSETLOCALエンドローカルは、このバッチファイルで使用される変数の存続時間を制御するためにバッチファイルでは使用されません。詳細はchange directory command cd ..not working in batch file after npm installの回答を参照してください。 npm.batも、jhove.batのようなコード化されていないバッチファイルではありません。

  2. コマンドラインSET JHOVE_HOME=%~dp0は、ドライブおよびパスがjhove.batの環境変数JHOVE_HOMEを定義しています。 %~dp0によって返されるパスは、常にバックスラッシュで終了します。 jhove*.zipが完全なパスの1つ以上のスペースを持つディレクトリに抽出された場合は、最後の文字列を二重引用符で囲むために最後にJHOVE_HOMEが使用される場所に注意する必要があります。

    コマンドラインSET CP=%JHOVE_HOME%\bin\JhoveApp.jarは、バッチファイルjhove.batへのパスをJavaパッケージの固定パスと名前で連結して、環境変数CPを定義します。 %~dp0はバックラッシュで終わるパスで、バックスラッシュで始まる文字列で連結されています。したがって、最終的にJavaパッケージファイルのパスに2つのバックスラッシュがあります。しかし、Windowsカーネルはこのエラーをパスで処理するため、実際には問題にはなりません。

    環境変数CPは、ユーザが最終的にコマンドラインjava -classpath %CP% Jhove %ARGS%で定義したEXTRA_JARSで修正されずに参照されます。ここでのエラーは%CP%であり、二重引用符で囲まずに指定されています。jhove*.zipが完全パスの1つ以上のスペースを持つディレクトリに実際に抽出された場合、予期しない動作が発生します。

  3. コマンドラインSET CP=%CP%:%EXTRA_JARSの最後にパーセント記号がありません。

  4. jhove.batの作家ではなく%ARGS%の最後のコマンドラインの使用に完全に役に立たない上記WHILEループを作る%*について明らかに何も知りませんでした。 jhove.batのためのはるかに良い

は次のようになります。

@echo off 
setlocal EnableExtensions 
set "JHOVE_HOME=%~dp0" 

set "EXTRA_JARS=" 

REM NOTE: Nothing below this line should be edited 
REM ######################################################################### 

set "CP=%JHOVE_HOME%bin\JhoveApp.jar" 
if not "%EXTRA_JARS%"=="" set "CP=%CP%:%EXTRA_JARS%" 

rem Set the CLASSPATH and invoke the Java loader 
java.exe -classpath "%CP%" Jhove %* 
endlocal 

実行java.exeは、Windowsのコマンド・インタプリタによって、環境変数PATHを経由していなければなりません。私はjhove.batの場合には、このタスクのために以下のコードを使用することを示唆している

使用

の最終バッチコードは、作業コード上に修正されるべきではない。

@echo off 
setlocal EnableExtensions 
set "InputFolder=%USERPROFILE%\test" 
set "OutputFolder=%USERPROFILE%\outputxml" 

echo Searching for bin\JhoveApp.jar in: 
echo. 
set "SearchPath=%CD%;%PATH%" 
set "SearchPath=%SearchPath:)=^)%" 
for /F "delims=" %%I in ('echo %SearchPath:;=^&ECHO %') do (
    echo %%I 
    if exist "%%~I\bin\JhoveApp.jar" (
     set "JHOVE_HOME=%%~I" 
     goto RunJHOVE 
    ) 
) 
echo. 
echo Error reported by %~f0: 
echo. 
echo Could not find bin\JhoveApp.jar in current directory and folders of PATH. 
echo. 
endlocal 
pause 
goto :EOF 

:RunJHOVE 
if "%JHOVE_HOME:~-1%" == "\" (
    set "CP=%JHOVE_HOME%bin\JhoveApp.jar" 
) else (
    set "CP=%JHOVE_HOME%\bin\JhoveApp.jar" 
) 
echo. 
echo Using %CP% 

md "%OutputFolder%" 2>nul 

rem for /F %%I in ('dir /A-D /B /S "%InputFolder%\*" 2^>nul') do (
rem  java.exe -classpath "%CP%" Jhove -m PDF-hul -h xml -o "%OutputFolder%\%%~nI.xml" "%%I" 
rem) 

for /R "%InputFolder%" %%I in (*) do (
    java.exe -classpath "%CP%" Jhove -m PDF-hul -h xml -o "%OutputFolder%\%%~nI.xml" "%%I" 
) 

endlocal 

入出力フォルダパスでありますあらかじめ定義された環境変数USERPROFILEを使用して、末尾にアスタリスクを付けずにバックスラッシュなしで定義します。 Find the path used by the command line when calling an executable上の彼の答えにMagooによって書かれた

A、わずかに変更されたコードは、JHOVEのJavaパッケージを見つけるために使用されます。バッチファイルは、ファイルが見つからない場合にエラーメッセージを表示し、ユーザがいずれかのキーを押すまでバッチ実行を停止する場合に、検索しているフォルダを出力します。

フォルダパスがバックスラッシュで終わるかどうかを考慮して、クラスパス変数CPが作成されます。 PATHのフォルダパスは、最後にバックスラッシュを付けずに定義する必要がありますが、インストール先は常にPATHに100%正しくないフォルダパスを追加します。しかし、結果がWindowsカーネルがこれを処理するので、パス内のどこでも\\になるかどうかは問題ではありません。これは、if exist "%%~I\bin\JhoveApp.jar"も常に動作しますが、このファイルの存在テストは、フォルダパスに応じて2つのバックスラッシュを使用してPATHにすることもできます。

次の出力フォルダは、フォルダが既に存在するかどうかをチェックせずに、フォルダの作成が正常に完了したかどうかを確認せずに作成されます。

バッチコードには、入力フォルダパスに再帰的に見つかる各ファイルにjhoveを実行するための2つのソリューションが含まれています。最初のものはコメントアウトされています。隠しファイルとシステムファイルに対しても機能する利点があります。 2番目の解決方法は、隠しファイルとシステムファイルでは機能しませんが、ここではほとんど必要ありません。したがって、第2の解決法が好ましいものである。

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

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • pause /?
  • set /?
  • setlocal /?

も読んでマイクロソフトの記事:パスまたはファイル名にスペースがあるとき

関連する問題