【问题标题】:Use Batch File Processing To Remove Last Character使用批处理文件处理删除最后一个字符
【发布时间】:2014-03-06 05:42:20
【问题描述】:

我有一个过程,其中传入的文件是 csv,并且在最后一个条目之后有尾随逗号。

我需要处理这个并在没有最后一个逗号的情况下将其发送出去,因为它会导致虚拟“空列”的验证错误

目前我有这段代码可以将每一行写入一个新文件:

for /f "tokens=* delims=" %%x in (file.csv) do echo %%i >> test.txt

我一直在尝试使用 echo %string:~0,-1% 之类的东西来删除尾随逗号,但我运气不佳。我不认为 %%i 可以像上面引用的字符串一样使用。我尝试将 %%i 写入字符串,但似乎我的语法也有误。

[编辑]

我确实通过 vbs 脚本运行文件以用管道 (, = |) 替换逗号,因此,如果在该过程中有更简单的方法可以做到这一点,在我搜索 stackoverflow 以尝试解决此问题之前问我发现这行我认为可能会有所帮助:

strNewText = strNewText.Substring(0,strNewText.Length-1)

strNewText 是保存更新数据的变量,但不起作用,现在查找和替换文本部分在我添加时实际上并没有运行:

rem CREATE Find And Replace Text VBS SCRIPT
echo Const ForReading = 1 > "%tmp%\fart.vbs"
echo Const ForWriting = 2 >> "%tmp%\fart.vbs"
echo strFileName = Wscript.Arguments(0) >> "%tmp%\fart.vbs"
echo strOldText = Wscript.Arguments(1) >> "%tmp%\fart.vbs"
echo strNewText = Wscript.Arguments(2) >> "%tmp%\fart.vbs"
echo Set objFSO = CreateObject("Scripting.FileSystemObject") >> "%tmp%\fart.vbs"
echo Set objFile = objFSO.OpenTextFile(strFileName, ForReading) >> "%tmp%\fart.vbs"
echo strText = objFile.ReadAll >> "%tmp%\fart.vbs"
echo objFile.Close >> "%tmp%\fart.vbs"
echo strNewText = Replace(strText, strOldText, strNewText) >> "%tmp%\fart.vbs"
echo strNewText = strNewText.Substring(0,strNewText.Length-1) >> "%tmp%\fart.vbs"
echo Set objFile = objFSO.OpenTextFile(strFileName, ForWriting) >> "%tmp%\fart.vbs"
echo objFile.WriteLine strNewText >> "%tmp%\fart.vbs"
echo objFile.Close >> "%tmp%\fart.vbs"

(所有的回显都是因为我在批处理运行时生成了 vbs,当一切都在一个文件中完成时,我倾向于发现事情更容易,然后这个 vbs 文件会在稍后的过程中被删除)。

【问题讨论】:

    标签: batch-file for-loop vbscript replace token


    【解决方案1】:
    @if (@This==@IsBatch) @then
    @echo off
    rem **** batch zone *********************************************************
    
        type inputfile.csv | cscript //nologo //e:javascript "%~f0" > outputfile.csv
    
        exit /b
    
    @end
    // **** Javascript zone *****************************************************
        while (!WScript.StdIn.AtEndOfStream) WScript.StdOut.WriteLine(WScript.StdIn.ReadLine().replace(/,[\s,]+$/,''));
    

    这是一个混合批处理/javascript 文件。另存为批处理文件,执行,inputfile.csv 文件将通过管道传输到 cscript.exe,cscript.exe 将执行同一批处理文件中包含的 javascript 代码,遍历管道数据并删除从最后一个逗号到末尾的所有逗号和最后的空格线。管道的输出被发送到 outputfile.csv

    已编辑 - 正如 cmets 中所述,也许我误解了这个问题,并且没有必要在行尾删除逗号,而只需删除最后的逗号。在这种情况下,替换表达式应该是

    ... .replace(/,$/,''));
    

    【讨论】:

    • 不需要全局匹配,因为搜索锚定在行尾。另外,我以不同的方式阅读了要求。我相信 OP 只想从每行的末尾删除一个 ,,所以我会使用 replace(/,$/,'')
    • @dbenham,对,不需要全局匹配。对于要求,我不确定,第一行谈到trailing commas after the last entry。也许你是对的。
    • 我起初也对“最后一个条目”的含义感到困惑。但是在阅读了整个问题之后,我决定将最后一个条目解释为每行的最后一个字段。
    【解决方案2】:

    对于您的问题,最简单的解决方案可能是sed for Windows

    C:\&gt;<b>sed "s/,$//" &lt;in.csv &gt;out.csv</b>

    您也可以编写一个简单的 VBScript 来做同样的事情:

    Set re = New RegExp
    re.Pattern = ",$"
    
    Do Until WScript.StdIn.AtEndOfStream
      WScript.Echo re.Replace(WScript.StdIn.ReadLine, "")
    Loop
    

    用法:

    C:\&gt;<b>cscript //NoLogo script.vbs &lt;in.csv &gt;out.csv</b>

    PowerShell 会是更好的选择:

    PS C:\&gt; <b>(Get-Content 'in.csv') -replace ',$' | Out-File 'out.csv'</b>

    建议为此使用批处理。

    【讨论】:

      【解决方案3】:

      我不确定这是否可行,但由于您只希望代码应用于最后一行,因此我尝试以不同于您的平均 for loop 的方式实现代码。

      @echo off
      setlocal enabledelayedexpansion
      set previous=
      set current=    
      ren file.csv file.tmp
      
      3<file.tmp (
      :loop
      set previous=!current!
      set /p current=<&3
      if "!current!" == "!previous!" (
      Echo !current:~0,-1! >> file.csv
      ) Else (
      Echo !current! >> file.csv
      goto :loop
      )
      )
      type file.csv
      Echo. &Echo Only delete if file.csv is not corrupt
      del /p file.tmp
      Endlocal
      

      这应该是做你想做的事。

      莫娜。

      【讨论】:

        猜你喜欢
        • 2017-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        相关资源
        最近更新 更多