批处理脚本 - 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.txt
或 call 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 -
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.txt
或 call 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 -