web-dev-qa-db-ja.com

Windowsコマンドシェルにワイルドカードパスを展開させる方法はありますか?

ときどき、cmdシェルではワイルドカードパスを展開できないため、本当に不便なことがあります。ディレクトリ内の100個のファイルをプログラムに渡す必要があり、*。extと入力できませんでした。代わりに、mingwの「ls」を使用してリストをファイルにダンプし、改行をスペースに置き換えて、cmdにコピーして貼り付けました。かなり悪夢です。

答えはノーだと思いますが、誰かがこれに対処したり、これを簡単にする方法を考えたりしましたか?

38
cemulate

DOS、およびその結果としてWindowsのcmd.exe、シェルによるワイルドカード展開はサポートされていません。拡張を行うのは常にアプリケーション次第でした。

つまり、拡張をサポートしていないアプリケーションを使用している場合は、常に別のルートを見つける必要があります。あなたは出来る:

  • FORループを使用 必要なすべてのファイルに対していくつかのコマンドを実行します
  • 使用する dir /b > list.txtdirコマンドを使用して展開を実行し、ファイルのリストをテキストファイルに入れます(cmdに貼り付けるコマンドのリストを作成するのが本当に必死である場合は、Excelの数式のようなものを使用できます。 Excelを使用してセルを転置できるため、すべてのファイル名が同じ行に表示されます。)
20
Malvineous

Windows 7にプリインストールされているPowershellを使用するだけです。Powershellはcmdコマンドを実行でき、パスの任意の場所のワイルドカードを認識します。

Powershellを起動するには、スタートメニューの検索ボックスに「powershell」と入力してEnterキーを押します。


アプリケーションがすべてのファイル名を含む文字列を期待する場合、これは適切なスクリプトです。

_$delimiter = " "
[string]$files = $nothing ; ls *.txt | % { $files += $_.fullname + $delimiter } ; application.exe $files
_

アプリケーションでファイル名のコンマ区切りリストが必要な場合は、_$delimiter = " "_を_$delimiter = ","_に変更します。

コードの説明:

  • _[string]$files = $nothing_-string型の空の変数を作成します
  • _;_-パイプラインではなく、複数のコマンドの区切り文字です。
  • _ls *.txt | % { $files += $_.fullname + $delimiter }_-すべてのテキストファイルのリストを取得し、すべてのファイル名を区切り文字で区切った文字列を作成します
  • _application.exe $files_-アプリケーションを呼び出し、ファイルリストをアプリケーションに渡します

_-recurse_を_ls *.txt_に追加することにより、ファイルパターンを再帰的に検索することもできるため、完全なコードは次のようになります。

_$delimiter = " "
[string]$files = $nothing ; ls *.txt -recurse | % { $files += $_.fullname + $delimiter } ; application.exe $files
_

編集:
イライラを避けるために、lsおよびdirは_Get-ChildItem_のエイリアスであり、_%_は_ForEach-Object_のエイリアスです。コードが短いため、エイリアスを使用してコードを保持しています。

編集2018/04/25:
2012年に、PowerShellを初めて使用しました。もちろん、より簡単な方法がありますが、glob拡張のunix/linux機能ほど簡単ではありません。

app.exe $(ls *.txt | % {$_.FullName})

説明:

  • $()は最初に内部の式を評価し、それ自体をその式の出力で置き換えます(バッククォートがbashで行うように)
  • _ls *.txt_は、グロブに一致するすべてのファイルのFileInfoオブジェクトを取得します_*.txt_
  • powerShellはオブジェクト指向であるため、各FileInfoオブジェクトのフルネームを出力する必要があります。 PowerShellで属性/プロパティに名前を付けるだけで、デフォルトで出力されます。 _% { $_.FileName }_がそれを行います。 _%_は、lsによって返されたすべての要素をループし、各オブジェクトFileNameを出力します。
9
wullxz

これはリストを提供し、expanded_listという名前の変数にそれを置きます。それをバッチファイルに入れ、myBatchFile name myPatternで実行します。パターンにスペースが含まれる場合は、パターンを引用符で囲みます。ファイルに一致しますが、dirsはありません。パラメータなしで実行すると、すべてに一致します。

@echo off
set expanded_list=
for /f "tokens=*" %%F in ('dir /b /a:-d "%~1"') do call set expanded_list=%%expanded_list%% "%%F"

echo expanded_list is: 
echo %expanded_list%

次に、my_command_exec %expanded_list%を使用してコマンドを実行できます

警告! cmd変数の最大サイズは8191文字(XP以降)であるため、オーバーフローする可能性があります。ユーティリティが完全なリストを常に提供するとは限りません。一方、最大cmd行の長さも8191なので、とにかくそれを実行することはできません。

8
wmz

これは、別のスレッドuser619818とスタイルのポスターへのコメントにあります)

DIRを使用すると、特定のタイプに一致するファイルのすべてのサブディレクトリを検索できます。

注:作成者がこれらのディレクトリが配置されているパス名を指定しなかったため、すべてのサブディレクトリが存在するかどうかを確認するルートディレクトリは「C:\ My Program\Root \」と見なされます。

DIR /B /S "C:\My Program\Root\*.ext"

これにより、ソースファイルの完全なファイルパスとファイル名が表示されます。

ファイル名だけが必要な場合は、次のようにする必要があります

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( Echo.%~nxA )

したがって、これらのファイルをすべて「C:\ My Program\Root\Sub Directories\*。ext」から「D:\ Singlefolder\*。ext」に移動する場合は、次のようにします。

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( MOVE "%~A" "D:\Singlefolder\%~nxA" /Y )

それが将来的に他の人を助けることを願っています。 :)

4
Ben Personick

これはcmd.exeで機能します

dir /b *.ext

または

echo | dir /b *.ext
3
user619818

これは古いですが、WindowsのLinuxサブシステムでは、PATHにbashを含めるのが一般的です。その場合は、これでうまくいくかもしれません:

bash -c 'cat *.txt'
2
Richard