質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

2回答

320閲覧

for文と環境遅延変数と疑似配列の組み合わせについて

pencil.lzh

総合スコア49

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

1クリップ

投稿2024/10/08 13:53

実現したいこと

Amazon s3のフォルダのls結果をWindowsコマンドプロンプトで変数に代入するバッチファイルを作成したいです。

発生している問題・分からないこと

for文でトークンに分けて%%aから始まるループ変数の4つ目の要素%%dに代入された値を
file[]という疑似配列に代入したいのですが、上手く代入されません。
for文を使って数字をインクリメントしたく、バッチでやるには環境遅延変数というものを使えばいいという情報をもとにsetlocal enabledelayedexpansionを最初に使っています。
for /fだとカウンタに当たる変数が無いように見えたのでその役割を果たす配列の添え字fcountと
配列名のfileを組み合わせて書こうとして
!file[!fcount!]!
%file[!fcount!]%
%file[%fcount%]%
などを試したのですが、期待通りに動作しませんでした。
どのように書けばよいでしょうか。
シンプルな実装方法を教えてください。

該当のソースコード

Windowsバッチファイル

1@echo off 2chcp 65001 3setlocal enabledelayedexpansion 4 5 6rem s3のlsの行数をファイルの個数とみなしてls_rowに代入 7for /f "usebackq" %%a in(`aws s3 ls s3://example-bucket-address --region ap-northeast-1 ^| find /c /v "") do set ls_row=%%a 8rem ここまでうまくいく 9 10set /a fcount=1 11 12rem 4つ目の要素%%dにs3のls結果のファイル名を格納されるので 13rem それをfile[]という配列っぽく命名した変数に代入したい 14for /f "tokens=1,2,3,4" %%a in('aws s3 ls s3://example-bucket-address --region ap-northeast-1') do ( 15rem ここでfile[]にファイル名を代入してループしたいが実際は入っていないように見える 16 set file[!fcount!]=%%d 17 set /a fcount=fcount+1 18 echo %file[!fcount!]% 19) 20 21rem 以降、格納されたfile[]についての後続処理を予定

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

変数がうまく展開・代入されない

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

batch

1@echo off 2chcp 65001 3setlocal enabledelayedexpansion 4set /a fcount=1 5for /f "tokens=1-4" %%a in ('aws s3 ls s3://example-bucket-address --region ap-northeast-1') do ( 6 set file[!fcount!]=%%d 7 call echo %%file[!fcount!]%% 8 set /a fcount=fcount+1 9)

・・・どうだろう?

投稿2024/10/09 10:42

v838-mon

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pencil.lzh

2024/10/13 02:23

こちらもありがとうございました。試したところうまくいきました。
guest

0

ベストアンサー

for文に文法エラーがありますが、それはさておくと、
%による環境変数展開は、文単位の構文解析に先立って行われます。
つまり、14行目から19行目までのfor文の構文解析や実行の前に、18行目の%file[!fcount!]%の展開は行われ、この段階では!による展開もまだなので、結局これはfile[!fcount!]という名前の環境変数の展開ですが、きっとそういう変な名前の変数には値はセットされてないでしょうから、空文字列になります。(未定義変数の参照はエラーにならず空文字列になるだけ)

もし仮にそこに問題が無かったとしても、fcount+1してからの参照なので、まだ設定していない変数の参照となり、結局は空文字列だと思います。セットした変数を参照したいなら、+1する前にしましょう。

CMD

1for /f "tokens=1,2,3,4" %%a in ('aws s3 ls s3://example-bucket-address --region ap-northeast-1') do ( 2 set file[!fcount!]=%%d 3 set file[!fcount!] 4 set /a fcount=fcount+1 5) 6set file

set file[!fcount!]で1行前でセットした変数名とその値、set fileで変数名がfileで始まる全変数名とその値が表示されます。

表示だけならこれでいいですが、括弧内で!file[%fcount%]!を参照しても、%fcount%forの前に展開されるので無意味です。個別に値を使いたいなら、callで括弧外のサブルーチンを呼び出す必要があります。

CMD

1for /f "tokens=1,2,3,4" %%a in ('aws s3 ls s3://example-bucket-address --region ap-northeast-1') do ( 2 set file[!fcount!]=%%d 3 call :DISPLAY 4 set /a fcount=fcount+1 5) 6exit /b 7:DISPLAY 8echo %fcount%: !file[%fcount%]! 9exit /b

投稿2024/10/08 14:42

otn

総合スコア85778

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pencil.lzh

2024/10/13 02:23

ほしい結果を得ることが出来ました。変数展開やサブルーチンの使用についてはまだ理解しきれていませんが、展開のタイミングによるものということまではわかりましたので、ベストアンサーとさせていただきます。
otn

2024/10/13 02:57 編集

後半のサブルーチンを呼ぶ手段は、この場合は、v838-mon さんの回答のような、CALLのアンドキュメンテッドな機能を使えば、コンパクトに書けます。 Windows2000時代に、CALLのこの機能を発見した時は、QAの回答でもよく書いてたのですが、アンドキュメンテッドなのはさておいても、正確に説明するのが面倒なので、自分では使う物の、最近は回答では自分からはあまり書いてません。使わなくてもサブルーチンにすれば出来るので。 多くの場合は「%の処理を繰り返したい回数だけCALLを前置する」で良いのですが、「CALLを書いても何を一度しかやらずに、CALLを画回数だけ何を繰り返しやるのか」をきちんと説明するためには「そもそもバッチファイルの構文解析は、、、」から入らないといけないので面倒です。
otn

2024/10/13 03:57

あと、echo off しなければ、%の展開と構文解析後のコマンドラインが表示されるので、様子が分かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問