2017-10-27 17 views
2

私はデータファイルから複数の行を読み込み、別のファイルに追加しています。問題は、追加された行の最後に出力ファイルに余分なスペースがあることです。元のデータファイルでは、行末にスペースがないため、私の要件に従って後続のスペースをトリムすることが必須です。私は可能なすべてのことを試みましたが、私はまだこれを達成できません。なぜECHOコマンドは余分なスペースをファイルに印刷しますか?

@echo off 
setlocal enabledelayedexpansion 
FOR /F "delims=" %%c IN (C:\Users\184863\Desktop\mydata.txt) DO ( 
echo %%c>>temp_data.txt 
) 
endlocal 

オプションは、私が試した:

  1. echo %%c>>temp_data.txtを...ライン

  2. set lines=%%c
    echo !lines!>>temp_data.txtの1つのスペースの終わりを取得...ラインの1巻のスペースの終わりを取得

  3. echo !lines:~0,-1!>>temp_data.txt ...最後のチャーラインは、ライン内のすべてのスペースはまた、あなたが持っている

答えて

2

(元のデータファイル内に存在しないラインの端部のみをトリミングする必要があります)トリミングされている...

  • set lines=!lines: =!
    echo !lines!>>temp_data.txt

    をトリミング削除する必要のある(特に)echo %%c>>temp_data.txtの端末スペース。これは、端末スペースの原因となる混乱の典型です。

  • +0

    は、私のファイル内の1つの小さな問題は、コード= 119888#[」のような1行をmydata.txtというend.butにスペースを取り除い198; ttps:!//egrul.nalog.ru/を] "私のコピーの後temp_data.txtのように" [code = 119888#/ egrul.nalog.ru/] "。 "!198; https:" characters removed.whatの間に、この問題のためのprint.anyの手がかりがない(!と:)の間の文字が見られました。 – Munu

    +0

    '%varname% 'が' code-block'の 'varname'の解析時の値を参照しているのと同じ方法で、'遅延拡張 'が呼び出されたときに'!varname! 'が' varname'の現在の値を参照しています'。コードは '!varname:string1 = string2!'のような部分文字列置換構文として '!'に続く文字列をインタープリスしています。あなたが実際に*必要な場合を除いて、 'enabledelayedexpansion'を削除してください。 – Magoo

    1

    ECHOによって無視されていないMagooとしては、すでに書いたecho行の末尾にスペースがあります。この末尾のスペースは、 ECHOの後に%%cの後に出力されます。

    通常、リダイレクトはコマンドラインの最後に書き込まれますが、どこにでも書き込むことができます。 の場合はコマンドラインのthis answerに表示されているように、以下のように、または途中のどこかで、最初にリダイレクションを書き込むこともできます。 ECHOコマンドラインの解析は、二重引用符で囲まれた文字列の外側の空白文字が引数区切り文字として解釈されないため、の各空白文字はECHOコマンドラインの問題であり、によって出力されます。には、>のようなリダイレクション演算子が含まれます。

    この

    は、コマンドの中から、このバッチファイルを実行するだけで echo Test>Test.txt  Test.txt後、末尾のスペースを持つバッチファイルを作成

    • コマンドプロンプトウィンドウを開き、
    • ことにより、容易に見ることができますプロンプトウィンドウ。

    出力はecho Test  1>Test.txtです。したがって、>は、Windowsのコマンドインタープリタで置き換えられ、 1>(スペース、1つの直角括弧)で終わりの行に移動します。上のこの移動は、コマンドラインによって、テキストTestの後に最初に後続のスペースが残され、結果としてECHOによっても出力されます。

    コマンドブロック全体を前処理する際のこのコマンドラインの変更は、コマンドプロンプトウィンドウ内で@echo offを使わずにオリジナルのバッチコードを実行することによっても確認できます。一行[code=119888#!198; ttps://egrul.nalog.ru/]含むmydata.txtたWindowsコマンドインタプリタ出力:>>temp_data.txt

    setlocal enabledelayedexpansion 
    FOR /F "delims=" %c IN (C:\Users\184863\Desktop\mydata.txt) DO (echo %c 1>>temp_data.txt) 
    (echo [code=119888#!198; ttps://egrul.nalog.ru/] 1>>temp_data.txt) 
    endlocal 
    

    末尾のスペースを 1>>temp_data.txtに残された唯一の単一のコマンドを含むコマンドブロックで全体 FORコマンドラインを前処理した後になりました。 FOR をECHOコマンドラインを実行する際に、今mydata.txt 1>>temp_data.txtから読み出しラインとの間に追加のスペースである末尾のスペースは、ECHOによっても出力されます。

    コマンドラインを前処理/解析し、バッチファイルに書かれているものではなく、Windowsコマンドインタープリタによって実際に実行されるものを常に考慮する必要があります。

    さらに遅延環境変数の展開は、ECHOコマンドを実行する前に!VariableName!のためのWindowsコマンドインタプリタによって処理されている%%cで参照ファイルから読み込んだ行にもたらされる有効になっています。行内の2つの感嘆符の間のすべてが変数名として解釈され、そのような環境変数がない場合は、参照される変数の値にそれぞれ置き換えられます。 ECHO実行前に、このコマンドラインの追加処理中に、Windowsコマンドインタープリタによって単一の(残りの)感嘆符が削除されます。

    解決方法1:遅延

    @echo off 
    setlocal EnableExtensions DisableDelayedExpansion 
    for /F "usebackq delims=" %%I in ("%USERPROFILE%\Desktop\mydata.txt") do >>temp_data.txt echo %%I 
    endlocal 
    

    環境変数の展開を明示的にいつものようにリテラル文字を感嘆符を解釈するために、このバッチコードで無効になっています。

    読み取る行のテキストファイルは、任意のWindowsコンピュータで動作するように、事前定義のWindows environment variableUSERPROFILEを二重引用符で囲んで指定します。二重引用符を使用するには、パスを指定して行を読み込むテキストファイル名として解釈されるファイル名文字列を取得するオプションusebackqが必要です。

    ラインは、おそらくそれを使用する良くない9の範囲1の数値で終わるように:

    echo %%c>>temp_data.txt 
    

    リダイレクト演算子がでECHOコマンドラインの開始と指定指定する方がよいです次に末尾にスペースがないecho %%c。詳細については、Using Command Redirection Operatorsに関するMicrosoftの記事を参照してください。

    FORは空の行を無視し、すべての行も使用するオプションでセミコロンで始まります。このバッチファイルで明示的に指定されていないオプションeol(行末)のデフォルトは;です。

    その上で、コマンドプロンプトウィンドウの代わりに、ダブルクリックの中から@echo ONに変更@echo offと、この小さなバッチファイルを実行するには、Windowsのコマンド・インタプリタが実際に実行されるものを見ることができます。

    for /F "usebackq delims=" %I in ("C:\Users\184863\Desktop\mydata.txt") do echo %I 1>>temp_data.txt 
    echo [code=119888#!198; ttps://egrul.nalog.ru/] 1>>temp_data.txt 
    

    だから、それができます実行前にバッチファイルの各コマンドラインを前処理した後、最終的にどのコマンドラインがWindowsのコマンドインタープリタによって実行されるのかがわかります。 >> 1>>(先頭にスペースを挿入しています)に置き換えられ、beginのリダイレクトはECHOコマンド行の最後に移動されました。

    解決方法2:

    @echo off 
    copy /B temp_data.txt+"%USERPROFILE%\Desktop\mydata.txt" temp_data.txt >nul 
    

    COPYコマンドは、最後に指定された単一のファイルにまとめて+演算子で指定された複数のファイルの内容をマージするために使用することができます。この機能は、既存のtemp_data.txtに、ユーザのデスクトップ上のmydata.txtの行を追加するためにここで使用されます。 COPYが、出力ファイルtemp_data.txt^Z(16進コード値1Aの代替制御文字SUB)に付加されないように、オプション/B(バイナリデータ)が必要です。

    このソリューションは、ファイルmydata.txtに含まれているものとは関係なく、最初のものより確実に優れています。

    使用されているコマンドとその動作方法を理解するには、コマンドプロンプトウィンドウを開き、次のコマンドを実行して、コマンドごとに表示されているすべてのヘルプページをすべてよく読んでください。

    • copy /?
    • echo /?
    • endlocal /?
    • for /?
    • setlocal /?
    0

    これはあなたのための簡単な修正する必要があります。
    1つ:遅延拡張を使用しないでください。
    2つ:echoコマンドの末尾のスペースを削除します。 Magoo..i @

    @ECHO OFF 
    SETLOCAL 
    SET "_File=C:\Users\184863\Desktop\mydata.txt" 
    SET "_Count=0" 
    SET "_Comment=Your Special Comment " 
    
    FOR /F "tokens=* delims=" %%c IN (%_File%) DO CALL :CountEcho %%c 
    
    ENDLOCAL 
    EXIT /B 0 
    
    :CountEcho 
    SET /A "_Count+=1" 
    IF /I %_Count% NEQ 100 (
        REM Line Not Equal to 100, Comment it 
        ECHO:%_Comment%%*>>"%~dp0temp_data.txt" 
    ) ELSE (
        REM Line 100 - No Comment 
        ECHO:%*>>"%~dp0temp_data.txt" 
    ) 
    GOTO :EOF 
    
    +0

    私のrequirmentは遅れた拡張を使用しなければならないと思います。特定のコメントを追加してください。私の要件を満たすための考えがありますか? – Munu

    +0

    @ムヌ間違ったユーザーに誤ってメッセージを送ったので、あなたのニーズに応えるソリューションを修正し、それを別のサブに分割して、あまり難読化しないことに決めました。 –

    関連する問題