2

実行された回数を単純にカウントする単純な統計プログラムを作成しようとしています。この問題は、時間の結果の変数を1より大きいトラッキングファイルにエコーするときに発生します。変数をファイルにエコーすることは不可能ですか?私は何が欠けていますか?:/

if not exist statistic_files (
mkdir statistic_files
)
cd statistic_files

if exist %username%-use_tracking (
FOR /F %%G IN (%username%-use_tracking) DO set /A uses=%%G+1
:: THE PROBLEM IS BELOW
echo %uses% > %username%-use_tracking
cd ..
)

if not exist %username%-use_tracking (
echo 1 > %username%-use_tracking
cd ..
)
4

6 に答える 6

2

変数値を設定し、後で同じ括弧で囲まれたコードブロック内の値にアクセスしているため、ファイルが既に存在する場合、コードは失敗します。%uses%行が解析されるときに展開され、コードブロック全体が一度に解析されます。したがって、エコーしている値は、FORループが実行される前に存在していた値であり、必要な値ではありません。

を使用して遅延拡張を有効にし、の代わりにを使用することで、問題を解決setlocal enableDelayedExpansionでき!uses!ます%uses%。詳細については、コマンドプロンプトhelp setから入力してください。ヘルプの約半分で、「最後に、遅延環境変数拡張のサポートが追加されました...」で始まる段落から読み始めてください。

ただし、拡張を遅らせる必要がない、より簡単な方法があります。IFブロック内で値を設定するだけで済みます。後でIFブロックの外でアクセスできます。

現在回避しているもう1つの問題がありますが、注意する必要が1>filenameあり>filenameます。同じことを実行します。これらは、標準出力(stdout)をファイルにリダイレクトするための命令です。1はstdoutのIDであり、番号が明示的に指定されていない場合のデフォルトです。2>filename標準エラー(stderr)をファイルにリダイレクトします。番号と。の間にスペースがあるため、番号をストリームIDとして解釈することは避けています>。しかし、注意しないと、いつかスペースがなくなり、番号が印刷されない理由について混乱するでしょう。リダイレクトを最後ではなく前に配置することで、問題を回避できます。>filename echo %uses%

したがって、これが完全に機能するソリューションです。

@echo off
setlocal
if not exist statistic_files mkdir statistic_files
cd statistic_files
set "file=%username%-use_tracking"

set "uses=1"
if exist %file% for /f %%G IN (%file%) do set /A uses=%%G+1
>%file% echo %uses%
于 2012-12-28T05:36:26.800 に答える
1

現在のファイルをテストすると(フォルダーを作成する上部のブロックを削除して、現在のディレクトリに2行を出力し、上部cd ..に追加するだけで)、次のようになります。set username=ken

  • 1初めて正しいコンテンツ(を含む1行)。
  • 2回目の1行のファイルECHO is on
  • 3回目のエラーメッセージ。

ECHOがオンになっているため、その出力が得られます。2回目の実行ではECHO、バッチファイルの2回目の実行時にその設定が行われます。

echoバッチファイルの先頭でオフにする必要があります。(これはechoコマンドの使用を妨げるものではありません。バッチファイル自体が出力されるのを防ぐだけです。)

これは私にとってはうまくいきます(私が上で述べた変更を加える):

@echo off
set username=ken

if exist %username%-use_tracking (
FOR /F %%G IN (%username%-use_tracking) DO set /A uses=%%G+1
:: THE PROBLEM IS BELOW
echo %uses% > %username%-use_tracking
)

if not exist %username%-use_tracking (
echo 1 > %username%-use_tracking
)

結果は次のとおりです。

  • 1初めて正しいコンテンツ(を含む1行)。
  • 2回目の1行のファイル2
  • 3回目の1行のファイル3。(そして、より多くの実行でなど。)

ファイル内のすべての行を保持したい場合は、代わりに最初の行echo %uses% > %username%-use_trackingecho %uses% > %username%-use_tracking(doubleに注意してください>>)に変更します。1つ>は上書きを意味し、2つは現在のコンテンツの最後に追加することを意味します。

于 2012-12-28T02:36:34.950 に答える
1

あなたの問題は、遅延変数拡張に直接関係しています。これを解決するには、プログラムの先頭に次の行を挿入します。

setlocal EnableDelayedExpansion

IFブロック内で変更された変数を、パーセントではなく感嘆符で囲みます。

echo !uses! > %username%-use_tracking

詳細については、このフォーラムで「遅延拡張」を探してください。このトピックには、次のような多くの回答があります。

forステートメントで変数を別の変数に設定します

于 2012-12-28T05:30:06.893 に答える
0

あなたはシングルを使用します>

すなわち:echo "Bla" > file.xyz

シングル>はファイル内のすべてを上書きするだけです

試す>>

echo "Blabla" >> file.xyz

ファイルの最後にコンテンツをdouble >>追加します

于 2012-12-28T02:29:40.810 に答える
0
  1. リダイレクト(追加モード)>>の代わりに使用します。>
  2. 間にディレクトリを変更する場合は、相対パスではなく、ログファイルに絶対パスを使用します。
于 2012-12-28T06:34:47.923 に答える
0

わかりました。コマンドの場合、変数に奇妙な影響を与えるため、遅延展開を使用する必要があることに気付きました。これらを述べてくれてありがとう。私はそれを適切に動作させることができました、まさに私がそれを望んでいたように、ここにあります:

@echo off
setlocal EnableDelayedExpansion

if not exist statistic_files (
mkdir statistic_files
cd statistic_files
goto skip
)
cd statistic_files
:skip
set "file=%username%-use_tracking"
set "uses=1"

if not exist %file% (
>%file% echo 1
cd ..
)
if exist %file% (
for /f %%G IN (%file%) do set /A uses=%%G+1
>%file% echo !uses!
cd ..
)
于 2012-12-28T14:22:46.227 に答える