Windows コマンドプロンプトからフルパスとファイルサイズのみを表示してファイルを再帰的にリストする

Windows コマンドプロンプトからフルパスとファイルサイズのみを表示してファイルを再帰的にリストする

特定のディレクトリとそのサブディレクトリにあるすべてのファイルのファイル名 (フルパスを含む) とファイル サイズ (つまり再帰的) を含むテキスト ファイルを生成しようとしています。理想的には、ファイル サイズにコンマは不要ですが (あっても構いません)、

次のコマンドはファイル サイズなしでこれを実行します。

dir /b /s /a:-D > results.txt

出力例は次のようになります。

C:\Users\Martin\Pictures\Table\original\PC120013.JPG  227298
C:\Users\Martin\Pictures\Table\original\PC120014.JPG  123234
C:\Users\Martin\Pictures\Table\original\PC120015.JPG  932344

これを単独で使用するのは不可能だと思いますdirが、間違っていることが証明されれば嬉しいです。コマンド プロンプトから使用できるコマンドのみを使用して、これを行う別の方法はありますか?

答え1

こうすればできるはずです:

@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

あまり効率的ではありません...大量のファイルを含むフォルダーに対して実行すると不確実な場合があるので、まずは小さなフォルダーで試してください。

「for /?」ヘルプテキストより(「I」の代わりに「a」を使用しました)

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

The modifiers can be combined to get compound results:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
               environment variable for %I and expands to the
               drive letter and path of the first one found.
%~ftzaI     - expands %I to a DIR like output line

答え2

代替案 #1: FOR /R は、私にとっては #2 よりも直感的です。
代替案 #2: FOR /F は、BrianAdkins の提案にある「名前内のスペース」の問題を修正します。
代替案 #3: パスが二重引用符で囲まれていることを除けば、FORFILES が私の選択です。

Brian や他の専門家は、より洗練されたソリューションを持っているか、または他の 12 個のソリューションを提案できるかもしれませんが、これら 3 つは機能します。FOR TOKENS を使用しようとしましたが、ヘッダーとフッターを削除する必要があったため、#1 に戻りました。小さな .bat ファイルを作成してそれを呼び出すことも検討しましたが、別のファイルが追加されます (ただし、関数と同様に、柔軟性が向上します)。

私は、スペースが埋め込まれたディレクトリとファイル名、200 文字以上のファイル名、拡張子のないファイル名、および小さなドライブのルートですべての代替案をテストしました (時間の都合上、少し遅いです。Brian が示唆したように、Windows エクスプローラーでの検索も同様に遅いです。そのため、Everything 検索アプリをインストールしました)。

代替案 1: FOR /R

最高(?)Brian の解決策がうまくいかなかった理由を解明しようとしながら、HELP FOR を見て、/R アプローチを試してみることにしました。(ファイルの作成は、代替案 #2 と同じです。)

@echo off & for /R "c:\deletelater\folder with spaces" %A in (*.*) do echo %~fA %~zA

例 - 作品(再帰を示すために上記とは異なるディレクトリ)

@echo off & for /R "c:\deletelater" %A in (*.*) do echo %~fA %~zA
c:\DeleteLater\Name with Spaces.txt 19800676
c:\DeleteLater\NoSpacesLongName.txt 21745440
c:\DeleteLater\Folder with Spaces\2nd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

代替案 2: FOR /F

BrianAdkins 氏の提案:@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

正解は:

@echo off & for /f "delims=*" %A in ('dir /s /b') do echo %~fA %~zA 

より完全なディレクトリを抑制し、ファイルに出力(追加)した場合の回答は次のとおりです。

@echo Results on %DATE% for %CD% >> YourDirFile.txt & echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA >> YourDirFile.txt

注: 「delims=*」はファイル名に使用できない文字を指定します。
注: 2 番目のコマンドは /a:-d を介してディレクトリも抑制します。
注: 誰かが異なる変数名を選択した場合に、変数と変数パラメータの区別を明確にするために、FOR 変数名を大文字にしました。
注: OP がファイルへの出力を要求したため、面白半分にファイルに追加しました。

ECHO のステータスも確認してリセットしたほうが良いと思います。

問題 - 名前内のスペース

Brian が提案した解決策では、スペースを含むファイル名やフォルダ名を処理できません (少なくとも私の Vista 構成では)。

例 - 間違い (区切りなし。OP ごとにディレクトリを非表示にしますが、強調のためファイル名の前後にサイズを含めます)

名前とサイズが切り捨てられています (6 ファイル中 4 つが間違っています):

@echo off & for /f %A in ('dir /s /b /a:-d') do echo %~zA %~fA %~zA
 C:\DeleteLater\Name
21745440 C:\DeleteLater\NoSpacesLongName.txt 21745440
 C:\DeleteLater\Folder
 C:\DeleteLater\Folder
 C:\DeleteLater\FolderNoSpaces\3rd
28726032 C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

例 - 正解 (画面に出力され、ファイルに追加されるわけではないことに注意してください)

@echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA
C:\DeleteLater\Name with Spaces.txt 19800676
C:\DeleteLater\NoSpacesLongName.txt 21745440
C:\DeleteLater\Folder with Spaces\2nd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

代替案 #3: FORFILES(引用問題)

このソリューションは、FORFILES ドキュメント ( ) の最後の 2 つの例から直接引用したものですforfiles /?

FORFILES /S /M *.doc /C "cmd /c echo @fsize"
FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

これらの例を組み合わせてファイルに書き込むと、答えは(ほぼ)次のようになります。

forfiles /s  /c "cmd /c if @isdir==FALSE echo @path @fsize" >>ForfilesOut.txt

出力ではパスが引用符で囲まれていることに注意してください。またはが切り替えられているかどうかは関係ありません。各
ディレクトリ を区切る空白行を追加することは、IF の簡単な拡張になります。echo onecho off

注意: マスクを使用すると、/m *.*拡張子のないファイルは返されません (例の最後のファイルなど)。

余談: これにより、各ディレクトリにそのディレクトリの内容のみを含むファイルが書き込まれます。これは
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt"OP が望んでいたものではありませんが、便利な場合もあります。

例 - 作品(ただしフルパスは引用符で囲みます)

forfiles /s  /c "cmd /c if @isdir==FALSE echo @path @fsize"

"c:\DeleteLater\Name with Spaces.txt" 19800676
"c:\DeleteLater\NoSpacesLongName.txt" 21745440
"c:\DeleteLater\Folder with Spaces\2nd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt" 28726032
"c:\DeleteLater\MoreFiles\A really really long file name that goes on and on 123456789 asdfghjkl zxcvnm qwertyuiop and still A really really long file name that goes on and on 123456789 qwertyuiop and still further roughly 225 characters by now.txt" 447
"c:\DeleteLater\MoreFiles\New Text Document no extension" 0

この例には、非常に長いファイル名と拡張子のないファイル名を持つ追加のディレクトリが含まれています。

問題: 引用符で囲まれたパス

では、OP の例に従って不要な(?)引用符を削除し、代替案 #3: FORFILES を保存する簡単な方法はありますか。(修辞的な質問: 引用符は機能ですか、それとも欠陥ですか?)

答え3

「du」コマンドは非常に便利で、Windows と Unix の両方で動作します (Windows PC から Linux Web サーバーに大量のデータを転送するときに、すべてのファイルがコピーされたかどうかを確認するために使用しました)。

du -ah "C:\your_dir" > "C:\file_list.txt"

出力:

15  C:\your_dir/.htaccess
608 C:\your_dir/folder/hello.txt
1.0 C:\your_dir/folder/subfolder/test.txt
1.0 C:\your_dir/folder/subfolder
1.2M    C:\your_dir/folder/world.txt
1.2M    C:\your_dir/folder
9.0 C:\your_dir/no_file_ending
11  C:\your_dir/sample document 1.txt
684K    C:\your_dir/sample document 2 - äöüßÄÖÜáà.txt
1.9M    C:\your_dir

ただし、Notepad では特殊文字を正しく表示できましたが、Notepad++ では正しく表示できませんでした (ANSI/UTF-8 エンコードの問題であるに違いありませんが、今は正確に分析する時間がありません)。また、ファイル名の後にサイズを表示する解決策も見つかりませんでした。サイズをバイトまたはキロバイトで表示するには、「h」ではなく「b」または「k」オプションを使用します。分析するフォルダーの外部でコマンドを実行すると問題が発生しました。したがって、正しいディレクトリ (この例では「C:\your_dir」) にコマンドを入力し、コマンドで指定するのが最善です。

答え4

これには追加のユーティリティが必要であることは理解しています、しかし、これをかなり簡潔に実現するには、sfk ユーティリティ:

sfk cwd +run -yes "sfk list -size -tab $qfile +toclip"

sfk fromclip > C:\_temp\sfk_list_output.txt

(私はsfkコマンドチェーンはこちら

関連情報