0

ディレクトリからすべてのテキストファイルを読み取り、特定の種類の文字列('volumelabel'を持つ行に含まれる)をそれぞれの別の文字列(replacewith)に置き換える必要があります。コードスニペットは次のとおりです。

for /r %%g in (*.txt) do (
 set filename=%%~nxg
 for /F "tokens=3 delims=<>" %%i in ('findstr "volumelabel" !filename!') do (
  set tobereplaced=%%i
 )
 echo !filename! has !tobereplaced! to be replaced by %replacewith%
 for /F "tokens=*" %%a in (!filename!) do (
  set str=%%a
  set str=!str:!tobereplaced!=%replacewith%!
  echo !str!>>new!filename!
 )
)

今私が直面している問題tobereplacedは、新しいファイルのすべての行に(文字通り)のみ印刷されることです。

set str=!str:!tobereplaced!=%replacewith%!
echo !str!>>new!filename!

が使用され、次のtobereplaced=replacewith場合に(値)を出力します

set str=%str:!tobereplaced!=%replacewith%%
echo !str!>>new!filename!

使用されている。誰かが私を助けることができますか?

4

1 に答える 1

1

(私の謙虚な意見では) 最も複雑でない解決策は、サブルーチンを使用してset str. 遅延拡張のレベルが 1 レベル以上深くなると、深刻な脳損傷を引き起こす傾向があります。ああ、あなたはおそらくset str次のようなことをすることであなたの行を修正することができます

call call call set str=%%%%str:%%tobereplaced%%=%replacewith%%%%%

...または類似。脳の損傷について私が言っていることがわかりますか?再帰に従うのは難しいです。

そこで、私の解決策を提案します。また、作業中に別の潜在的な問題を 1 つまたは 2 つ修正しました。*.txt を再帰的に検索しているので、forループがサブディレクトリ内で見つけたテキスト ファイルを処理できるようにしました。私はこれをテストしていないので、グロテスクなエラーが発生した場合はお知らせください。

@echo off
setlocal enabledelayedexpansion
set replacewith=whatever

for /r %%g in (*.txt) do (
    set newfile=%%~dpng.new%%~xg
    for /F "tokens=3 delims=<>" %%i in ('findstr "volumelabel" "%%g"') do (
        set "tobereplaced=%%i"
        echo %%~nxg has !tobereplaced! to be replaced by %replacewith%

        rem combining your for loops this way makes the second only fire if the first is true
        rem using "findstr /n" in your for loop preserves blank lines
        for /F "delims=" %%a in ('findstr /n "^" "%%g"') do (

            rem ...but you have to strip off the line numbers
            set "str=%%a" && set "str=!str:*:=!"

            rem "call :repl" to work around the delayed expansion conundrum
            call :repl "!str!" "!tobereplaced!" "%replacewith%" str
            echo !str!>>!newfile!
        )
    )
)
goto :EOF

:repl <line> <find> <replace> <var>
setlocal enabledelayedexpansion
set "line=%~1"
set "line=!line:%~2=%~3!"
set "%4=%line%"
goto :EOF

警告: テキスト ファイルに感嘆符、等号、またはカラットが含まれている場合、textfile.new.txt に変換されない可能性があります。


価値があるのは、私があなたの立場にあった場合、バッチファイルを使用する代わりに、おそらくsedを使用することです(必要なのはバイナリだけです)。スクリプトも必要ありません。次のようなワンライナーとして実行できます。

for /r %I in (*.txt) do sed -r "s/volumelabel/replacement/ig" "%I" > "%~dpnI.new%~xI"

ところで、表記の種類のhelp for説明については、 の最後の数ページを参照してください。%~dpnI

于 2013-03-12T12:41:32.773 に答える