• ベストアンサー

HDDのフルパスをテキストファイルに高速に書き出す

HDDのフルパス(含むファイル名)一覧をテキストファイルで高速に書き出すツールなどを探しています。 ネットで検索するとツールとしてかなりの候補がありますが 正直、高速(短時間)で処理できるツールがどれなのか?良くわかりません。 昨今、HDD(SSD)も2TBなど容量が大きなものが当たり前の時代になっています。 例えば、HDD(D:ドライブ)のD:¥以下の全てのサブフォルダーを含めて 全てチェックして書き出すのは 時間が必要と思われなるべく短時間で処理できそうなツール等を紹介ください。 ツールで無く、コマンド(Powershell、bat)で処理出来て コマンドの方が高速ならコマンドで処理する方法を紹介ください。 なお、テキストファイルに書き出す内容は、フルパス(含むファイル名)だけで ファイルサイズや更新日などの付属情報は必要無いです。

質問者が選んだベストアンサー

  • ベストアンサー
  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.12

同時に接続はしないで、1台ずつ差し替えて接続するのなら、動作すると思います。 別の方法では、ボリューム シリアル番号を使っても識別は出来ると思います。 この場合は、同時に接続しても識別出来ると思います。 カレントをドライブレターにして、vol とコマンドを入力すると、16進数の、4桁-4桁で表示されます。 vol | find "5B37-158A">nul && set ID=X みたいな感じで。 ボリューム シリアル番号は、フォーマットした時に生成されるものです。なので、フォーマットしたら変わります。

NuboChan
質問者

お礼

お世話になりました。 こちらで相談させていただいて  満足できるコードができました。   REM ドライブレターの全フォルダー名のみを階層を含めて出力 REM ドライブ直下のファイル名(フルパス)の出力にも対応 REM ---------------------------------------------------- @echo on set /p D="ドライブを入力してください <例> K --> " REM 「cd D:\フォルダー名」と入力することで、現在のディレクトリであるDドライブの特定のフォルダーにアクセスすることができます。 REM しかし、現在の作業ドライブやディレクトリがCドライブである場合、このコマンドは機能しません。 REM その場合は、コマンドプロンプトでCDコマンドを使わずに、コマンド「cd /d d:」を使用します。 REM このコマンドを実行すると、現在のDドライブのディレクトリに移動し、現在のドライブもDドライブに変更されます。 cd /d %D%: REM ゴミ箱とドライブ内のゴミ箱の中身をクリア rd /s /q %D%:\$Recycle.Bin REM サーチ先のドライブに移動して以下の作業を行う(書き出しもサーチ先になる) REM -- ドライブレターの全フォルダー名のみを階層を含めて出力 REM /b : ファイルやディレクトリ名のみ (要約や日時、サイズなどを省略) REM /ad : フォルダ名のみ REM /s : 指定したディレクトリおよびそのサブディレクトリ(階層も含める) dir /b /ad /s > C:\temp\temp1.txt REM -- /a-d ドライブ直下のファイル名のみを出力 dir /b /a-d > C:\temp\temp2.txt REM ファイル結合してコピー テキストで書き出す。 デフォルト --> Copy /a copy /a C:\temp\temp2.txt + C:\temp\temp1.txt C:\temp\temp.txt REM tempファイル削除(del /Q --> 確認メッセージが表示されずに DEL コマンドを実行) del /Q C:\temp\temp1.txt del /Q C:\temp\temp2.txt REM 出力ファイルをソート sort /o C:\temp\FileName_ListUp.txt C:\temp\temp.txt REM シート前のファイルは削除(del /Q --> 確認メッセージが表示されずに DEL コマンドを実行) del /Q C:\temp\temp.txt REM ------------------------------------------------ REM Vol1, Vol2, Vol3という変数にボリューム名をセット set Vol1=K-N set Vol2=456 set Vol3=789 REM IDという変数を空でセット set ID= REM wmicコマンドでHDDのvolumenumberを取得し、findコマンドでVol1, Vol2, Vol3の値を検索 REM errorlevelの値に応じて、IDという変数にX, Y, Zの値をセット wmic logicaldisk get volumename | find "%Vol1%" if %errorlevel% EQU 0 set ID=X wmic logicaldisk get volumename | find "%Vol2%" if %errorlevel% EQU 0 set ID=Y wmic logicaldisk get volumename | find "%Vol3%" if %errorlevel% EQU 0 set ID=Z REM 調査結果の表示、numの値で、serialnumberの中に一致するものがあった場合、ID=X,Y,Zを表示し REM ドライブを加味したファイル名に変名。 REM 変名にrenameを使うと上書きが出来ないのでmoveを使用(オプションなしでは上書き確認無し) REM serialnumberの中に一致するものがなかった場合、IDには何もセットせずに表示。 if defined ID ( echo Match found. ID=%ID% move C:\temp\FileName_ListUp.txt C:\temp\%ID%_FileName_ListUp.txt ) else ( echo No match found. ID=%ID% ) echo. echo " ---- 処理が終了しました。 -----" & pause exit /b

その他の回答 (11)

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.11

長い文字列を以後、何回も参照する場合は、変数に入れた方が良いと思います。 set List=C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt 表示されたものをリダイレクト > で書き込んで、追記する場合は、 >> で追記する。 ドライブ直下のファイルをフルパスで表示する場合は、for の繰り返しを使うしかないでしょう。 ・・・で、こんな感じ・・・。 @echo off set List=C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt set /p D="ドライブを入力してください <例> x --> " cd /d %D%: dir /b /ad /s>%List% (for %%i in (%D%:\*) do ( echo %%~fi ))>>%List%

NuboChan
質問者

お礼

REM ドライブレターの全フォルダー名のみを階層を含めて出力 REM ドライブ直下のファイル名(フルパス)の出力にも対応 REM ---------------------------------------------------- 変数の使い方(コード)をありがとうございます。 便利な情報で嬉しいです。 その後、 %~dp0 の利用方法と言うのを探して利用してみました。 少しコードが見やすくなりました。 欲が出て色々(あれもこれも)を追加して、現在のコードは以下のようになりました。 (すこし無駄なことはしていますが、後で見直しても判るようにしました) 現在、追加したい事があります。 ’------------------------ このコードで同じUSB端子で3つのHDDを順番に処理する予定ですが そうなるとドライブレターが全て同じなので FileName_ListUp.txtはテキスト内容が異なる3つの同名ファイルが出来上がります。 3つの同名ファイルは、最終的には結合されて1つのファイルになる予定ですが ファイル名が同一なのでこのままでは結合できません。 なのでFileName_ListUp.txtができるとそれぞれ3つのファイルは手動で適当に変名する必要があります。 そこで、コードでHDD毎に変名処理ができないか?です。 まず考えたのは、ファイル名に日付を以下の参考URLのように追加する事ですが これは、各ドライブ直接区別できないので適当ではないと考えています。 <バッチファイル中で日付をファイル名に使用する> https://atmarkit.itmedia.co.jp/ait/articles/0405/01/news002.html 前置きが長くなりましたが、 お知恵をお借りしたいのは、ドライブ(X,Y,Z)を個別に自動判断して ファイル名に付加する方法は無いでしょうか ? msinfo32(システム情報)などでディスクドライブの名称や情報は見れるのでどうにかなりそうだとは思いますが どうすべきかアイデアがありません。 ’---------------------------------------------------- @echo off set /p D="ドライブを入力してください <例> x --> " cd /d %D%: REM サーチ先のドライブに移動して以下の作業を行う(書き出しもサーチ先になる) REM -- ドライブレターの全フォルダー名のみを階層を含めて出力 REM -- ドライブ直下のファイル名は出力しない dir /b /ad /s>temp1.txt REM -- /d /s ドライブ直下のファイル名のみをフルパスで出力 (a-d ドライブ直下のファイル名のみ出力) dir /b /d >temp2.txt REM ファイル結合してコピー REM %~dp0 ---> BATがあるフォルダを表す copy /Y temp2.txt + temp1.txt %~dp0temp.txt REM tempファイル削除 del /Q temp1.txt del /Q temp2.txt REM 出力ファイルをソート sort /o %~dp0temp.txt %~dp0temp.txt rename %~dp0temp.txt FileName_ListUp.txt cls & echo "終了しました" & pause exit /b

NuboChan
質問者

補足

以下を作成しましたが、 まだ未検証で合っているかも不明です。 アドバイスできる事あればお願いします。 ’-------------------------------------- REM ドライブレターの全フォルダー名のみを階層を含めて出力 REM ドライブ直下のファイル名(フルパス)の出力にも対応 REM ---------------------------------------------------- @echo off set /p D="ドライブを入力してください <例> x --> " cd /d %D%: REM サーチ先のドライブに移動して以下の作業を行う(書き出しもサーチ先になる) REM -- ドライブレターの全フォルダー名のみを階層を含めて出力 REM -- ドライブ直下のファイル名は出力しない dir /b /ad /s>temp1.txt REM -- /d /s ドライブ直下のファイル名のみをフルパスで出力 (a-d ドライブ直下のファイル名のみ出力) dir /b /d >temp2.txt REM ファイル結合してコピー REM %~dp0 ---> BATがあるフォルダを表す copy /Y temp2.txt + temp1.txt %~dp0temp.txt REM tempファイル削除 del /Q temp1.txt del /Q temp2.txt REM 出力ファイルをソート sort /o %~dp0temp.txt %~dp0temp.txt rename %~dp0temp.txt FileName_ListUp.txt REM ------------------------------------------------ REM num1, num2, num3という変数に任意の番号をセット (番号の数字は、実際の数字とは異なる仮の数字) set num1=123 set num2=456 set num3=789 REM IDという変数を空でセット set ID= REM wmicコマンドでHDDのserialnumberを取得し、findコマンドでnum1, num2, num3の値を検索 REM errorlevelの値に応じて、IDという変数にX, Y, Zの値をセット wmic diskdrive get serialnumber | find "%num1%" if not errorlevel 1 set ID=X wmic diskdrive get serialnumber | find "%num2%" if not errorlevel 1 set ID=Y wmic diskdrive get serialnumber | find "%num3%" if not errorlevel 1 set ID=Z REM 調査結果の表示、numの値で、serialnumberの中に一致するものがあったため、ID=X,Y,Zが表示。 REM serialnumberの中に一致するものがなかった場合、IDには何もセットされすに表示。 if defined ID ( echo Match found. ID=%ID% ) else ( echo No match found. ID=%ID% REM ドライブを加味したファイル名に変名 rename %~dp0FileName_ListUp.txt %ID% _FileName_ListUp.txt cls & echo "終了しました" & pause exit /b

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.10

for %%F in (D:\*) do ( echo %%~nxF ) > D:\output\file_list.txt これは、 dir /b /a-d>D:\output\file_list.txt で、いいと思いますけど。 1) と )2 を続けているなら、 dir /b /a-d>%D%:\output\file_list.txt フルパスのファイル名なら、for で繰り返す必要がありますがファイル名だけなら、上記でいいと思います。 dir /b で /s を付けた場合は、フルパス表記になります。 ( /s : サブフォルダも含める。) /s が無い場合は、パスは付きません。

NuboChan
質問者

お礼

ありがとうございます。 以下の1)に 教えていただいた dir /b /a-d /s>C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt を追加すれば良さそうだと思いますが 理解が追いついていません。 理解できぬなりに以下のようなコードを考えましたが なぜだか?階層のファイル名も表示されています。 欲しいのは、  ドライブ直下のファイル名のみをフルパス   ドライブレターの全フォルダー名のみを階層を含めて出力 ------> ファイル名は必要ない です。 REM文を参照ください。 間違いの訂正をお願いします。 REM ドライブレターの全フォルダー名のみを階層を含めて出力 REM ドライブ直下のファイル名(フルパス)の出力にも対応 REM ---------------------------------------------------- @echo off set /p D="ドライブを入力してください <例> x --> " cd /d %D%: REM -- ドライブレターの全フォルダー名のみを階層を含めて出力 REM -- ドライブ直下のファイル名は出力しない dir /b /ad /s>C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt REM -- /a-d /s ドライブ直下のファイル名のみをフルパスで出力 (a-d ドライブ直下のファイル名のみ出力) dir /b /a-d /s>C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt cls & echo "終了しました" & pause exit /b

NuboChan
質問者

補足

すいません。 /a-d /s ではなく、/d でした。 (/d /s では上手く処理できない ?) 単純にファイル結合で処理できそうなので以下のようなコードになりましたが パスの部分の指定が長くなって醜いいコードでがこれで良いでしょうか ? 改善点あればお願いします。 REM ドライブレターの全フォルダー名のみを階層を含めて出力 REM ドライブ直下のファイル名(フルパス)の出力にも対応 REM ---------------------------------------------------- @echo off set /p D="ドライブを入力してください <例> x --> " cd /d %D%: REM -- ドライブレターの全フォルダー名のみを階層を含めて出力 REM -- ドライブ直下のファイル名は出力しない dir /b /ad /s>C:\Users\TAC_\Desktop\Mp3_MergeDrive\temp1.txt REM -- /d /s ドライブ直下のファイル名のみをフルパスで出力 (a-d ドライブ直下のファイル名のみ出力) dir /b /d >C:\Users\TAC_\Desktop\Mp3_MergeDrive\temp2.txt REM ファイル結合 copy C:\Users\TAC_\Desktop\Mp3_MergeDrive\temp2.txt + C:\Users\TAC_\Desktop\Mp3_MergeDrive\temp1.txt C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt REM tempファイル削除 del /Q C:\Users\TAC_\Desktop\Mp3_MergeDrive\temp1.txt del /Q C:\Users\TAC_\Desktop\Mp3_MergeDrive\temp2.txt cls & echo "終了しました" & pause exit /b

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.9

またまたまた、ごめんなさい。 cd コマンドで、ドライブ間の移動は、 /d が必要でした。 cd %D%:  ↓↓ cd /d %D%: もしくは、pushd コマンドで、 pushd %D%:

NuboChan
質問者

お礼

ありがとうございます。 教えていただいたコードでドライブレターが反映できるようになりました。 実状況で検証していくともう一つ欲しいbatが候補に上がりました。 以下の1)と2)を合わせたbatです。 つまり、 指定ドライブレターの全フォルダー名のみを階層を含めて出力(A)し そこにドライブ直下のファイル名のみを取得(B)して合わせて出力(A+B)する 希望の処理が出来るようにコードを改変していただけませんか ? REM 1)ドライブレターの全フォルダー名のみを階層を含めて出力 REM 最上部のファイル名は出力されない REM ---------------------------------------------------- @echo off set /p D="ドライブを入力してください <例> x --> " cd /d %D%: dir /b /ad /s>C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt cls & echo "終了しました" & pause exit /b REM 2)ドライブ直下のファイル名を取得して、`D:\output\file_list.txt`というテキストファイルに書き込みます。 @echo off setlocal enabledelayedexpansion REM 指定したドライブの直下のファイル名を取得 for %%F in (D:\*) do ( echo %%~nxF ) > D:\output\file_list.txt echo ファイル一覧をテキストファイルに書き込みました。 pause

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.8

ごめんなさい。またまた訂正。 \ が無かった。 dir /b /a-d /s>%D%:\test.txt

NuboChan
質問者

補足

batファイルを以下で試してみましたが batが保存されているホルダー内のファイルのみが対象になっていて 出力されるのはドライブ指定(D)内のファイル群ではありませんでした。 @echo off set /p D="ドライブを入力してください <例> x: --> " cd %D%: dir /b /a-d /s>C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt cls & echo "終了しました" & pause exit /b ドライブ指定は、試しに  D と D: の2つ試しましたが同じ結果でした。 どこかで、間違っていますか ?

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.7

2024/01/29 19:55 回答No.6 訂正 ごめんなさい。 ファイルだけだから、 dir /b /a-d /s>%D%:test.txt でした。

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.6

ちなみに、普通のバッチファイルなら、 @echo off set /p D="ドライブを入力してください <例> x :" cd %D%: dir /b /s>%D%:test.txt ------------------------------ for の繰り返しだと、1個ずつ追記書き込みになるので、例えばファイルが500個あれば、500回書き込むことになるので高速にはならないと思います。

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.5

@powershell -c "'#'+(gc '%~f0' -Raw) | iex" &exit/b $Inp=Read-Host "ドライブを入力してください <例> x " Set-Location "$($Inp):" Get-ChildItem -Recurse -File | Select-Object -ExpandProperty FullName | Out-File "$($Inp):\test.txt" -Encoding default ---------------------------------------- ドライブ名のアルファベット1文字を入力して、Enterキーを押して下さい。 バッチファイルの保存時の文字コードは ANSI か Shift_JIS相当にして下さい。

NuboChan
質問者

お礼

コードをありがとうございます。 現在、コードを実情で試すべく以下のように一部追加、修正しました。 上手く処理できました。 FileName_Listup.bat @powershell -c "'#'+(gc '%~f0' -Raw) | iex" &exit/b $Inp=Read-Host "ドライブを入力してください <例> x " Set-Location "$($Inp):" Get-ChildItem -Recurse -File | Select-Object -ExpandProperty FullName | Out-File "C:\Users\TAC_\Desktop\Mp3_MergeDrive\FileName_ListUp.txt" -Encoding default Write-Output "処理終了しました。" Read-Host " キーを入力してください。"

  • luka3
  • ベストアンサー率72% (454/624)
回答No.4

バッチでいいなら、これでもできると思いますけど @DEL K:\test.txt @FOR /R K:\ %%I IN (*) DO @ECHO %%~fI>>K:\test.txt

NuboChan
質問者

お礼

最初の質問に記載しましたように 主眼が高速処理なのでFOR文だと高速化が見込めないとのコメントをいただきました。 今回は、For文を利用しない方法を希望いたします。

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.3

>これで正解なら以前教えて頂いたbatにする方法 ~ で完成だと思いますが いかがでしょうか ? はい、いいと思います。

NuboChan
質問者

お礼

>はい、いいと思います。 ありがとうございます。 肝心な事をもう一点解決するのを忘れていました。 ターゲットとなるドライブが外付けなので ドライブレターが時々変わります。 ps1(bat)で「Set-Location K:」「Out-File "K:\test.txt"」 の「K」を書き換えた Xドラブレター用のモノを必要数準備する事もできますが スマートではないのでps1(bat)のコードの中で指定できるように改造したいのですが どのように変更すれば良いですか ?

  • UY-Scuti
  • ベストアンサー率85% (18/21)
回答No.2

cd K: ls -Rec -File | select -Exp FullName | sc "K:\test.txt" 長々と書くなら、 Set-Location K: Get-ChildItem -Recurse -File | Select-Object -ExpandProperty FullName | Set-Content "K:\test.txt" Out-File を使うなら、エンコードのパラメーターを入れた方が良いです。 無いと、文字コードが UTF-16 になります。UTF-16 はあまり使わないと思います。 Out-File "K:\test.txt" ↓↓ Out-File "K:\test.txt" -Encoding default

NuboChan
質問者

お礼

UY-Scutiさん、アドバイスありがとうございます。 PowerShellの超初心者なのでPowerShell上で エラー>コード書き換え>実行を繰り返しました。 結果、教えてもらったコードを以下のように解釈して 一応、出力されましたが、正解ですか ? Set-Location K: Get-ChildItem -Recurse -File | Select-Object -ExpandProperty FullName | Out-File "K:\test.txt" -Encoding default これで正解なら以前教えて頂いたbatにする方法 powershell -c "'#'+(gc '%~f0' -Raw) | iex" &exit/b Set-Location K: Get-ChildItem -Recurse -File | Select-Object -ExpandProperty FullName | Out-File "K:\test.txt" -Encoding default で完成だと思いますが いかがでしょうか ?

関連するQ&A