windows cmdシェルを使用してワイルドカードパスを展開する方法はありますか?


37

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

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


2
代わりにPowershellなどを使用することを検討しましたか?

I suspect the answer will be no, but has anyone dealt with this or come up with any way to make this easier? 実際、私は反対の問題を抱えています。コマンドインタープリターがそのリストを文字列として扱い、ワイルドカードとして解釈されないようにする方法を見つけようとしています。例えば、for %i in (foobar baz really?) do @echo %i(最後の項目を扱いますreally?ファイル名のワイルドカードとして)、およびという名前のファイルがない場合はそれをスキップreally1reallyzなど☹、
Synetech

1
@Synetech- ?Windowsファイルシステム内のファイル名の正当な文字ではありません。文字はワイルドカードとしてのみ解釈できます。MSDNの「ファイル、パス、名前空間の命名」および TechNetのワイルドカード文字の使用を参照してください。
jww

回答:


18

DOS、したがってWindows ' cmd.exeは、シェルによるワイルドカード拡張をサポートしていませんでした。拡張を行うのは常にアプリケーション次第でした。

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

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

彼は、dirの結果をファイルに出力し、フィルタリングとコピーを手動で処理するのは悪夢だと説明しました。wmzの答えともちろん私のものは、ファイルのコンテンツを手動でフィルタリングしなくても機能します。
wullxz

1
@wullxz:おそらく、しかし、Powershellに不慣れな人がこれを一回限りにしたい場合、それはかなり速くなる可能性があります-そして、このサイトの背後にあるアイデアは、すべてのスキルレベルの人々が今、そしてあなたは私の答えがあなたのものほど良くないと思うので、将来、だから本当に私に言う必要はありません。
悪意のある

1
「DOS、したがってWindowsのcmd.exeは、シェルによるワイルドカード拡張をサポートしていませんでした。」-マイクロソフトによると、そうではありません。TechNetでのワイルドカード文字の使用を参照してください。(しかし、実際には正しいと思います:o。さもなければ、ファイルが一致しない理由を
解明

1
@jww:あなたが投稿したリンクは、ワイルドカード文字の標準的な使用方法を説明していますが、シェルによって展開されているという言及は見当たりません。UNIX(およびそれ以降のLinuxおよびMac)とは異なり、Microsoftは実装する個々のアプリケーションごとにワイルドカード拡張を残し、コマンドラインパラメーターをそのまま渡します。
Malvineous

1
DOSコマンド 'dir Filespec / b'は、ファイルのリストを1行に1つずつ作成するため、非常にうまく機能します。追加の '/ s'スイッチを使用すると、ファイル名は完全修飾(絶対)され、ファイル名を取得する他のコマンドラインプログラムにforループを介して簡単に渡すことができます。Windowsには適切なグロビング機能がないため、できる限り最善の方法です。
デビッドA.グレー

9

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です。短いので、エイリアスを使用してコードを保持します。

EDIT 2018/04/25:
2012年に戻って、私はPowerShellにかなり慣れてきました。もちろん、より簡単な方法がありますが、unix / linuxのグロブ拡張機能ほど簡単ではありません。

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

説明:

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

2
PSは要求を確実に満たすことができますが、PSに慣れるためのアドバイスは適切です-あなたが提案するほど単純ではありません。ランニングstart notepad++ *.txt(意思とすると、すべてのテキストファイルを開くために-それはとして使用するメモ帳++ ません複数の名前を処理を)どこにもあなたを取得しません
WMZ

1
あなたはそれを回避することができdir *.txt | % { notepad++.exe $_ }ます。私はnotepad ++を持っていないので、簡単なメモ帳でそれを試してみましたが、うまくいきました。このコマンドは、現在のディレクトリ内のすべてのtxtファイルのリストを受信し、リストをループして次のコマンドに渡し、リストをループして、ファイル名をパラメーターとしてnotepad ++を実行します。
wullxz

はい、しかしこれは同等ではありません。考えてみてgrep "a b c"見つけるために、任意の「AB cは」リストを展開されるだろう列挙された文字列、のを
WMZ

5
コマンドを実行すると、パラメータなどの項目のリストでは、コマンド実行することと同じではありません各要素に複数回をパラメータとして、リストから。別の例:copy a+b+c resultcopy a result copy b result copy c result。(とgrepユーティリティなどのやっていることはそれを呼び出して、PSに存在するselect-string
WMZ

1
賛成、それはOPが説明するためにチャイムを気にしないのは残念だ
...-wmz

8

これにより、リストが表示され、という名前の変数に配置されます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であるため、とにかく実行することはできません。


引数が指定されていない場合、expanded_listは現在のディレクトリ内のすべてのファイルに設定されることに注意してください。
ジェイソンM1 14

3

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

dir /b *.ext

または

echo | dir /b *.ext

これはファイル名に対してのみ機能し、パスの一部には機能しません。たとえば、dir /b TortoiseSVN\bin\sv*.exeとが表示さsvn.exesvnadmin.exeます。しかしdir /b TortoiseSVN\bi*\svn.exe、構文エラーを示しています。
スタイフ

1
確認してくださいdir /s /b。これにより、完全なパスが得られます。
WesternGun

3

注、これは別のスレッド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 )

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


1

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

bash -c 'cat *.txt'

Windows cmdでは一重引用符は特別ではないため、上記のコマンドをcmdから実行すると機能しないことに注意してください。また、これはCygwinまたは他のbash環境を持つシステムにも適用されます
-phuclv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.