短い質問
文字列全体がファイルに書き込まれるように出力をファイルにリダイレクトしながら"foo 1"
、コマンドで文字列をエコーするにはどうすればよいですか?echo
C:\>echo foo 1>foo.txt
C:\>type foo.txt
foo
C:\>xxd -g1 a.txt
0000000: 66 6f 6f 20 0d 0a foo ..
上記の実験は、コマンドの がリダイレクト演算子の一部であると解釈される"foo "
ため、 のみがファイルに書き込まれることを示しています。文字列の末尾に不要なスペースがあるファイルに書き込むため、これは解決策ではないことに注意してください。"1"
1>
echo foo 1 > foo.txt
"foo 1 "
長い質問
次の Windows バッチ スクリプトを検討してください。
@echo off
call :log "start script"
call :log "foo"
call :log "end script"
goto :eof
:log
echo %~1>>log.txt
goto :eof
このスクリプトを実行すると、意図したとおりに動作します。つまり、log.txt に 3 行のログを書き込みます。
C:\>foo
C:\>type log.txt
start script
foo
end script
次に、ログの 2 行目が から に変更された次のスクリプトについて考えてみましょ"foo"
う"foo 1"
。
@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof
:log
echo %~1>>log.txt
goto :eof
これにはちょっとした驚きがあります。以下の出力でわかるように、ログ ファイルの"foo"
代わりに表示されます。"foo 1"
C:\Users\pals3\Desktop>foo
C:\Users\pals3\Desktop>type log.txt
start script
foo
end script
@echo off
スクリプトから を含む最初の行を削除してからスクリプトを実行すると、なぜこれが発生するのかを簡単に理解できます。
C:\>foo.cmd
C:\>call :log "start script"
C:\>echo start script 1>>log.txt
C:\>goto :eof
C:\>call :log "foo 1"
C:\>echo foo 1>>log.txt
C:\>goto :eof
C:\>call :log "end script"
C:\>echo end script 1>>log.txt
C:\>goto :eof
C:\>goto :eof
ここでわかるよう>>log.txt
に、スクリプトに がある場合は常に、コマンド インタープリターはそれを同義の構文である に置き換えます1>>log.txt
。これは、ログを記録するコマンドが"foo 1"
として実行されecho foo 1>>log.txt
、単に"foo"
ログ ファイルに書き込むことを意味します。
echo %~1>>log.txt
簡単な解決策は、スクリプト内のステートメントを に置き換えることecho %~1 >>log.txt
です。
@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof
:log
echo %~1 >>log.txt
goto :eof
ただし、これは、ログの各行の末尾にスペース文字が追加されることを意味します。これは、ペダンティックな観点からは理想的ではなく、grep を使用してログ ファイルをフィルタリングする場合に少し混乱します。
C:\>foo
C:\>type log.txt
start script
foo 1
end script
C:\>xxd -g1 log.txt
0000000: 73 74 61 72 74 20 73 63 72 69 70 74 20 0d 0a 66 start script ..f
0000010: 6f 6f 20 31 20 0d 0a 65 6e 64 20 73 63 72 69 70 oo 1 ..end scrip
0000020: 74 20 0d 0a
:log
ログのすべての行の最後に余分なスペースを書き込まずに、上記の驚きを取り除く方法でサブルーチンを書く方法はありますか?