it-swarm-ja.tech

コマンド出力から変数を設定する際のWindowsバッチヘルプ

簡単な検索コマンドを実行して、出力をWindowsバッチファイルの変数にリダイレクトする必要があります。

私はこれを試しました:

set file=ls|find ".txt"
echo %file%

しかし、それは機能しません。

このコマンドを実行すると、問題なく動作します。

set file=test.txt
echo %file%  

したがって、明らかに、コマンド出力が変数に設定されていません。誰か助けてもらえますか?ありがとう

21
Steve

パイプを使用してコマンドを使用する方法を見つけるだけです。これが私のコマンドです(svnリポジトリのヘッドリビジョンを抽出します)。

SET SVN_INFO_CMD=svn info http://mySvnRepo/MyProjects
FOR /f "tokens=1 delims=" %%i IN ('%SVN_INFO_CMD% ^| find "Revision"') DO echo %%i
9
Grokwik

まず第一に、あなたの質問に期待しているように見えることは、UNIXシェルでは不可能です。シェルは、ls|find fooがコマンドであり、test.txtがコマンドではないことをどのように知る必要がありますか?ここで何を実行しますか?そのため、UNIXシェルはそのようなことに対してバックティックを持っています。とにかく、私は余談です。

シェルから環境変数を複数行の文字列に設定することはできません。したがって、lsの出力が完全に適合しないため、問題が発生します。

ただし、ここで本当に必要なのは、すべてのテキストファイルのリストです。必要に応じて、それを行うのは非常に簡単です。これらすべての例の主要部分は、forループであり、一連のファイルを繰り返し処理します。

すべてのテキストファイルに対してアクションを実行する必要があるだけの場合:

for %%i in (*.txt) do echo Doing something with "%%i"

これはスペースを含むファイル名でも機能し、.txtのように、名前の真ん中にfoo.txt.barが含まれているファイルを誤ってキャッチしません。あなたのアプローチはあなたが望むほどきれいではないことを指摘するだけです。

とにかく、ファイルのリストが必要な場合は、ちょっとしたトリックを使って配列などを作成できます。

setlocal enabledelayedexpansion
set N=0
for %%i in (*.txt) do (
    set Files[!N!]=%%i
    set /a N+=1
)

この後、Files[0]Files[1]などの複数の環境変数が作成されます。それぞれに1つのファイル名が含まれています。あなたはそれをループすることができます

for /l %%x in (1,1,%N%) do echo.!Files[%%x]!

(ここでは不要な新しい行を出力していることに注意してください。これを削除することもできますが、コードを1行追加します:-))

その後、必要に応じて、非常に長いファイル名の行を作成できます。あなたはパターンを認識するかもしれません:

setlocal enabledelayedexpansion
set Files=
for %%i in (*.txt) do set Files=!Files! "%%i"

これで、ファイル名が非常に長い行になりました。あなたが望むもののためにそれを使用してください。これは、ファイルの束を別のプログラムに渡す場合に便利です。

ただし、バッチファイルの最大行長は約8190文字です。そのため、1行に含めることができるものの数に制限があります。そしてはい、ファイルの束全体を1行で列挙すると、ここでオーバーフローする可能性があります。

元のポイントに戻ると、そのバッチファイルにはコマンド出力をキャプチャする方法がありません。他の人は以前にそれを指摘しました。この目的でfor /fを使用できます。

for /f %%i in ('dir /b') do ...

これにより、コマンドによって返された行が繰り返され、途中でトークン化されます。たぶんバッククォートほど便利ではないかもしれませんが、ほとんどの目的で十分に十分です。

デフォルトでは、トークンは空白で分割されるため、ファイル名「Foo bar」を取得すると、突然、%%iに「Foo」、%%jに「bar」しか表示されなくなります。それは混乱する可能性があり、そのようなことがファイルの一覧を取得するためだけにfor /fを使用したくない主な理由です

一部のプログラム引数と衝突する場合は、アポストロフィの代わりにバックティックを使用することもできます。

for /f "usebackq" %%i in (`echo I can write 'apostrophes'`) do ...

これもトークン化することに注意してください。あなたが与えることができるいくつかのより多くのオプションがあります。それらはhelp forコマンドで詳しく説明されています。

6
Joey

setコマンドには、標準入力から値を読み取るように指示する/pオプションがあります。残念ながら、それへのパイピングはサポートしていませんが、既存のファイルの最初の行からの値の読み取りはサポートしています。

したがって、変数を最初の*.txtファイルの名前に設定するには、次のようにします。

dir /b *.txt > filename.tmp
set /p file=< filename.tmp
del /q filename.tmp

=の前後にスペースを入れないことが重要です。

P. S.いいえfors、いいえtokens

3
Olexa

短い答えは:しないでください!

Windows Shell env varは最大32 Kbを保持でき、プログラムからの出力をプログラムに保存するのは安全ではありません。そのため、保存できません。バッチスクリプトでは、別のプログラミングを採用する必要がありますスタイル。プログラムからのすべての出力が必要な場合は、ファイルに保存します。特定のプロパティのみをチェックする必要がある場合は、チェックを実行してエラーレベルメカニズムを使用するプログラムに出力をパイプします。

@echo off

type somefile.txt | find "somestring" >nul
if %errorlevel% EQU 1 echo Sorry, not found!
REM Alternatively:
if errorlevel 1 echo Sorry, not found!

ただし、Perlスタイルの論理演算子を使用する方がエレガントです。

@echo off

(type somefile.txt | find "somestring" >nul) || echo Sorry, not found!
1
Henrik

findによって出力された最後のアイテムを返すバッチファイルを次に示します。

@echo off

ls | find ".txt" > %temp%\temp.txt
for /f %%i in (%temp%\temp.txt) do set file=%%i
del %temp%\temp.txt
echo %file%

forには、コマンド出力を解析するための構文for /f "usebackq"ですが、コマンド内のパイプを処理できないため、出力を一時的な場所にリダイレクトしました。

lsにアクセスできる場合は、bashなどのより優れたバッチ言語、またはpythonRubybashでも、cmdスクリプトよりも20倍向上します。

1
Barry Kelly

DOSでは使用できませんが、Windowsコンソールにはforコマンドがあります。コマンドプロンプトで「help for」と入力するだけで、すべてのオプションが表示されます。単一の変数を設定するには、これを使用できます:

for /f %%i in ('find .txt') do set file=%%i

ウィンドウはデフォルトでは変数を1回しか展開しないため、これは「find .txt」から返される最初の行でのみ機能することに注意してください。 here のように、遅延拡張を有効にする必要があります。

0
shf301

あなたが本質的にしていることは.txtファイルをリストすることです。これで、forループを使用してdir cmdを上書きできます。

for /f "tokens=*" %%i in ('dir /b *.txt') do set file=%%i

または、lsを使用したい場合は、パイプで検索する必要はありません。

for /f "tokens=*" %%i in ('ls *.txt') do set file=%%i
0
ghostdog74

コマンド出力から変数を設定する例:

FOR /F "usebackq" %%Z IN ( `C:\cygwin\bin\cygpath "C:\scripts\sample.sh"` ) DO SET BASH_SCRIPT=%%Z

c:\cygwin\bin\bash -c '. ~/.bashrc ; %BASH_SCRIPT%'

また、DOSシェルでFORコマンドをテストする場合は、%Zの代わりに%Zを使用するだけで十分です。それ以外の場合は、次のエラーが表示されます。

%%Z was unexpected at this time.
0
desm