批处理脚本 - Trim 功能和删除空行

Batch Script - Trim functionality and Removing blank lines

Trim 函数:

批处理脚本中是否有 trim 功能?即删除尾随和开始 spaces。需要将 trim 功能应用于文本文件中的所有行。 下面是我到目前为止得到的脚本。但这会删除任何第一个字符,希望它只删除 spaces,如果有的话。

For /F "tokens=*" %%A in (Temp.txt) do (
    set line=%%A
    echo(!line:~1!>>Temp.txt
)

例如: 输入 =

[Space][Space]This is just a example message[Space][Space]
[Space]This is second example message[Space][Space]
This is third example message[Space]

输出=

This is just a example message
This is second example message
This is third example message

[Space] 等于 1 space 个字符。

删除空行:

如果只有 spaces/tabs 而没有其他行,如何删除它们? 例子 : 下面是包含两个 space 的一行,然后是如何从文本文件中删除整行。

[SPACE][SPACE]
Sub TrimSpace
    If LCase(Arg(1)) = "l" then 
        Do Until Inp.AtEndOfStream
            Line=Inp.readline
            outp.writeline LTrim(Line)
        Loop
    ElseIf LCase(Arg(1)) = "r" then
        Do Until Inp.AtEndOfStream
            Line=Inp.readline
            outp.writeline RTrim(Line)
        Loop
    ElseIf LCase(Arg(1)) = "lr" then
        Do Until Inp.AtEndOfStream
            Line=Inp.readline
            outp.writeline Trim(Line)
        Loop
    ElseIf LCase(Arg(1)) = "lc" then
        Count = Cint(LCase(Arg(2)))
'       msgbox count
        Do Until Inp.AtEndOfStream
            Line=Inp.readline
'           msgbox Line & "  " & Len(Left(Line,Count)) & "  " & Len(Mid(Line, Count)) & "  " & Len(Space(Count)) & "  " & Len(Line)  
'           msgbox Left(Line,Count) & "End" & vbcrlf & Space(Count) & "End"
            If Left(Line,Count) = Space(Count) then
                outp.writeline Mid(Line, Count +1)
            Else
                outp.writeline LTrim(Line)
            End If
        Loop
    End If
End Sub

Sub BlankLine
    Set RegEx = New RegExp
    RegEx.Pattern = "^\s+$"
        If LCase(Arg(1)) = "e" then
            Do Until Inp.AtEndOfStream
                Line=Inp.ReadLine
                If Len(Line) <> 0 Then
                    OutP.WriteLine Line
                End If
            Loop
        ElseIf Lcase(Arg(1)) = "a" then
            Do Until Inp.AtEndOfStream
                Line=Inp.ReadLine
                If Len(Line) <> 0 Then
                    If RegEx.Test(Line) = False then
                        OutP.WriteLine Line
                    End If
                End If
            Loop
        End If
End Sub

两个脚本都需要以下 4 行。

Set Arg = WScript.Arguments
set WshShell = createObject("Wscript.Shell")
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout

你需要给子机打电话

使用trim

cscript //nologo "path to script.vbs" "" l < "c:\inputfile" > "C:\outputfile"

和空行

cscript //nologo "path to script.vbs" "" a < "c:\inputfile" > "C:\outputfile"

https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121 是您可以下载 filter0.8.zip 的地方,它是一个易于使用的文件。 Filter有19个文本文件函数和很多选项,是vbs处理文本文件的示例代码。显示它是多么容易。所有单独的功能都在一个子中。

@echo off
setlocal

(for /F "tokens=*" %%a in (input.txt) do (
   if "%%a" neq "" (
      set "line=%%a"
      setlocal EnableDelayedExpansion
      call :rTrim
      echo !line!
      endlocal
   )
)) > output.txt
move /Y output.txt input.txt
goto :EOF

:rTrim
if "!line:~-1!" neq " " exit /B
set "line=!line:~0,-1!"
goto rTrim

上一个批处理文件基于这些操作细节:

  • FOR /F命令不处理空行,即删除个空行。
  • "TOKENS=*" 选项删除前导空格。
  • 当未给出 DELIMS= 选项且一行仅包含空格 and/or 制表符时,%%a 为空。

所以唯一复杂的部分是正确的trim...

以下是优化的纯批处理解决方案,无论必须 trimmed 多少字符,它的执行都与行数成线性关系。此解决方案也是对称的,因为它在每行的开头和结尾都添加了 trim 个空格和制表符,并且完全删除了所有结果为空的行。该脚本希望文件 trimmed 作为参数传递。例如 xtrim test.txtcall xtrim "c:\test\test.txt"。结果覆盖原始文件。

XTRIM.BAT

@echo off
setlocal disableDelayedExpansion
>"%~1.new" (
  for /f "usebackq eol= tokens=*" %%A in ("%~1") do if "%%A" neq "" (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    for %%k in (
      4096 2048 1024 512 256 128 64 32 16 8 4 2 1
    ) do for /f "eol= tokens=*" %%B in ("!ln:~-%%k!.") do (
      setlocal disableDelayedExpansion
      if "%%B" equ "." (
        endlocal
        set "ln=!ln:~0,-%%k!"
      ) else endlocal
    )
    echo !ln!
    endlocal
  )
)
move /y "%~1.new" "%~1" >nul

与任何纯批处理脚本一样,以上无法处理长度超过 ~8191 字节的行,如果处理大文件,它会变得非常慢。但是,此解决方案的速度与纯批处理的速度差不多。

我有一个更简单、更快速的解决方案,使用 JREPL.BAT - 一个对文本文件执行正则表达式 find/replace 的实用程序。 JREPL.BAT 是一个混合 JScript/batch 脚本,可在任何 Windows XP 及更高版本的机器上本地运行。

下面的一行具有完全相同的功能,除了它实际上没有限制(理论上每行最大约 2 GB),并且在处理任何可观大小的文件时速度要快得多。

JXTRIM.BAT

@jrepl "^[ \t]*(.*?)[ \t]*$" "?:false" /jmatch /f %1 /o -



我相信上述两种解决方案都能满足 OP 的要求。然而,他们并没有完全按照要求去做。我 trim 制表符和空格,但 OP 只要求 trim 前导和尾随空格。 OP 只要求在删除整行时删除制表符,因为它是空的或因为它包含制表符 and/or 个空格。

以下修改完全符合 OP 规定的规范:

XTRIM2.BAT

    @echo off
    setlocal disableDelayedExpansion
    >"%~1.new" (
      for /f "usebackq tokens=* eol= delims= " %%A in ("%~1") do if "%%A" neq "" (
        set "ln=%%A"
        setlocal enableDelayedExpansion
        for %%k in (
          4096 2048 1024 512 256 128 64 32 16 8 4 2 1
        ) do for /f "tokens=* delims= " %%B in ("!ln:~-%%k!.") do (
          setlocal disableDelayedExpansion
          if "%%B" equ "." (
            endlocal
            set "ln=!ln:~0,-%%k!"
          ) else endlocal
        )
        for /f "eol= " %%B in ("!ln!") do echo !ln!
        endlocal
      )
    )
    move /y "%~1.new" "%~1" >nul

JXTRIM2.BAT

@jrepl "^[ ]*(.*[^ \t](.*[^ ])?)[ ]*$" "?:false" /jmatch /f %1 /o -