无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 2180|回复: 43

[求助] bat处理文本,如何保留所有空行

  [复制链接]
发表于 2023-11-22 13:48:11 | 显示全部楼层 |阅读模式
本帖最后由 nfans 于 2023-11-22 15:25 编辑

需求:
1,删除a.txt中行首4个空格(所有行:行首指定数量
2,同时保留原文件中所有空行(所有空行不做处理)

本人对批处理是门外汉,利用百度来的代码已实现删指定数量行首字符,但同时也会删除所有空行,求助如何在此基础上兼顾保留空行。

因不能上传附件,还请复制文本测试,在此感谢各位大神!

初测批处理代码:

  1. @echo off
  2. set fn=a.txt
  3. (for /f "usebackq delims=" %%i in ("%fn%")do (
  4. echo;%%i>con
  5. set "h=%%i"
  6. setlocal enabledelayedexpansion
  7. echo;!h:~4!
  8. endlocal))>b.txt
  9. pause
复制代码
待测示例文本如下:a.txt
  1.     Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
  2.     Set colItems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
  3.     For Each objItem in colItems
  4.             OSA = objItem.OSArchitecture
  5.     Next

  6.     Const HKLM = &H80000002

  7.     Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

  8.     If OSA = "64-bit" Then
  9.             oReg.GetStringValue HKLM,"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\XReplace","UninstallString",UninstallString
  10.             If Not IsNull(UninstallString) Then InstallLocation = Replace(UninstallString,"uninstall","XReplace")
  11.     Else
  12.             oReg.GetStringValue HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XReplace","UninstallString",UninstallString
  13.             If Not IsNull(UninstallString) Then InstallLocation = Replace(UninstallString,"uninstall","XReplace")
  14.     End If

  15.     Set WshShell = WScript.CreateObject("WScript.Shell")

  16.     If IsNull(InstallLocation) Then
  17.             WshShell.Popup "软件未安装!", 5, "错误", 0
  18.             WScript.Quit
  19.     End If

  20.     Name = Array("XReplace.exe")
  21.     Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,(Debug)}!\\.\root\cimv2")
  22.     Set colProcessList = objWMIService.ExecQuery ("Select * from Win32_Process")
  23.     For Each objProcess In colProcessList
  24.             For Each Process In Name
  25.                     If LCase(objProcess.Name) = LCase(Process) Then
  26.                             objProcess.Terminate()
  27.                     End If
  28.             Next
  29.     Next

  30.     Set objFSO = CreateObject("Scripting.FileSystemObject")

  31.     If objFSO.FileExists(InstallLocation) Then
  32.             Set ado_stream = CreateObject("ADODB.Stream")
  33.             ado_stream.Type = 1
  34.             ado_stream.open
  35.             ado_stream.LoadFromFile InstallLocation
  36.             ado_stream.position = 215133
  37.             ado_stream.Write HexToByte("E9B701000090")
  38.             ado_stream.position = 256771
  39.             ado_stream.Write HexToByte("E9CE02000090")
  40.             ado_stream.position = 277094
  41.             ado_stream.Write HexToByte("01")
  42.             ado_stream.position = 313599
  43.             ado_stream.Write HexToByte("B80100")
  44.             ado_stream.position = 313855
  45.             ado_stream.Write HexToByte("B80100")
  46.             ado_stream.position = 314442
  47.             ado_stream.Write HexToByte("B80100")
  48.             ado_stream.position = 314901
  49.             ado_stream.Write HexToByte("B80100")
  50.             ado_stream.SaveToFile InstallLocation, 2
  51.             ado_stream.Close
  52.             Set ado_stream = Nothing
  53.     End If

  54.     WshShell.Popup "超级字符串批量替换工具 v4.2.5 破解补丁" & vbnewline & vbnewline & "制作:ChiShingChan  编程语言:VBScript",10,"完成",0

  55.     Function HexToByte(hexStr)
  56.             Set xmldom = Wscript.CreateObject("Microsoft.XMLDOM")
  57.             Set byteObj= xmldom.createElement("byteObj")
  58.             byteObj.dataType = "bin.hex"
  59.             byteObj.nodeTypedValue = hexStr
  60.             HexToByte=byteObj.nodeTypedValue
  61.     End Function
复制代码




发表于 2023-11-22 14:42:20 | 显示全部楼层
本帖最后由 newyun 于 2023-11-22 14:48 编辑


@echo off
setlocal enabledelayedexpansion

set input_file=a.txt
set output_file=output.txt

for /f "tokens=*" %%a in (%input_file%) do (
    set line=%%a
    echo !line:~4!>> %output_file%
)
del a.txt /q
move output.txt a.txt

点评

你好,这个代码会删除所有行首的空字符,不是指定数量,并且也会删除所有空行  详情 回复 发表于 2023-11-22 15:01
回复

使用道具 举报

 楼主| 发表于 2023-11-22 15:01:51 | 显示全部楼层
newyun 发表于 2023-11-22 14:42
@echo off
setlocal enabledelayedexpansion

你好,这个代码会删除所有行首的空字符,不是指定数量,并且也会删除所有空行
回复

使用道具 举报

发表于 2023-11-22 15:03:38 | 显示全部楼层
我测试过是删除前4。比如原a.txt是
11111111  11111111  
22222222  22222222  
33222233  33333333  
42222444  44444444  
11222211  11111111  
22222222  22222222  
33222233  
44222244  
删除完后是

1111  11111111  
2222  22222222  
3333  33333333  
4444  44444444  
1111  11111111  
2222  22222222  
3333  
4444  

点评

前面表述不清,主要是删行首若干空格,并同时保留空行  详情 回复 发表于 2023-11-22 15:06
回复

使用道具 举报

 楼主| 发表于 2023-11-22 15:04:51 | 显示全部楼层
本帖最后由 nfans 于 2023-11-22 15:24 编辑

首楼代码测试结果参照: b.txt

多删了空行…… 需求简单实现不易

  1. Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
  2. Set colItems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
  3. For Each objItem in colItems
  4.         OSA = objItem.OSArchitecture
  5. Next
  6. Const HKLM = &H80000002
  7. Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
  8. If OSA = "64-bit" Then
  9.         oReg.GetStringValue HKLM,"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\XReplace","UninstallString",UninstallString
  10.         If Not IsNull(UninstallString) Then InstallLocation = Replace(UninstallString,"uninstall","XReplace")
  11. Else
  12.         oReg.GetStringValue HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XReplace","UninstallString",UninstallString
  13.         If Not IsNull(UninstallString) Then InstallLocation = Replace(UninstallString,"uninstall","XReplace")
  14. End If
  15. Set WshShell = WScript.CreateObject("WScript.Shell")
  16. If IsNull(InstallLocation) Then
  17.         WshShell.Popup "软件未安装!", 5, "错误", 0
  18.         WScript.Quit
  19. End If
  20. Name = Array("XReplace.exe")
  21. Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,(Debug)}!\\.\root\cimv2")
  22. Set colProcessList = objWMIService.ExecQuery ("Select * from Win32_Process")
  23. For Each objProcess In colProcessList
  24.         For Each Process In Name
  25.                 If LCase(objProcess.Name) = LCase(Process) Then
  26.                         objProcess.Terminate()
  27.                 End If
  28.         Next
  29. Next
  30. Set objFSO = CreateObject("Scripting.FileSystemObject")
  31. If objFSO.FileExists(InstallLocation) Then
  32.         Set ado_stream = CreateObject("ADODB.Stream")
  33.         ado_stream.Type = 1
  34.         ado_stream.open
  35.         ado_stream.LoadFromFile InstallLocation
  36.         ado_stream.position = 215133
  37.         ado_stream.Write HexToByte("E9B701000090")
  38.         ado_stream.position = 256771
  39.         ado_stream.Write HexToByte("E9CE02000090")
  40.         ado_stream.position = 277094
  41.         ado_stream.Write HexToByte("01")
  42.         ado_stream.position = 313599
  43.         ado_stream.Write HexToByte("B80100")
  44.         ado_stream.position = 313855
  45.         ado_stream.Write HexToByte("B80100")
  46.         ado_stream.position = 314442
  47.         ado_stream.Write HexToByte("B80100")
  48.         ado_stream.position = 314901
  49.         ado_stream.Write HexToByte("B80100")
  50.         ado_stream.SaveToFile InstallLocation, 2
  51.         ado_stream.Close
  52.         Set ado_stream = Nothing
  53. End If
  54. WshShell.Popup "超级字符串批量替换工具 v4.2.5 破解补丁" & vbnewline & vbnewline & "制作:ChiShingChan  编程语言:VBScript",10,"完成",0
  55. Function HexToByte(hexStr)
  56.         Set xmldom = Wscript.CreateObject("Microsoft.XMLDOM")
  57.         Set byteObj= xmldom.createElement("byteObj")
  58.         byteObj.dataType = "bin.hex"
  59.         byteObj.nodeTypedValue = hexStr
  60.         HexToByte=byteObj.nodeTypedValue
  61. End Function

复制代码
回复

使用道具 举报

 楼主| 发表于 2023-11-22 15:06:46 | 显示全部楼层
newyun 发表于 2023-11-22 15:03
我测试过是删除前4。比如原a.txt是
11111111  11111111  
22222222  22222222  

前面表述不清,主要是删行首若干空格,并同时保留空行
回复

使用道具 举报

发表于 2023-11-22 15:15:36 | 显示全部楼层
ChiShingChan在论坛的,可以用VBS来完成这个题目。

点评

原需求就是来自于论坛这个代码插件不能使用,试了多个浏览器都没搞定…… 图片能上传却不能上传txt是何解? [attachimg]534773[/attachimg]  详情 回复 发表于 2023-11-22 15:32
回复

使用道具 举报

发表于 2023-11-22 15:28:25 | 显示全部楼层
@echo off
setlocal enabledelayedexpansion

set "inputFile=a.txt"
set "outputFile=b.txt"

if not exist %inputFile% (
echo File %inputFile% does not exist.
exit /b 1
)

for /f "tokens=*" %%a in (%inputFile%) do (
set "line=%%a"
set "line=!line:~0,1!!line:~1!"
echo !line! >> %outputFile%
)
del /q a.txt
move b.txt a.txt

点评

是删所有行行首,并保留空格,请注意审题,所以结果还不正确 空格与空行别弄混了  详情 回复 发表于 2023-11-22 15:39
回复

使用道具 举报

发表于 2023-11-22 15:28:59 | 显示全部楼层
  1. @echo off&setlocal enabledelayedexpansion&set n=0
  2. ::删除行首4个字符保留其它空行到b.txt
  3. (for /f "delims=" %%a in ('findstr /n .* a.txt') do (
  4.         set "t=%%a"
  5.     if !n!==0 (echo=!t:~6!)else echo=!t:~2!
  6.     set /a n+=1
  7. ))> b.txt
  8. pause
复制代码

评分

参与人数 1无忧币 +5 收起 理由
smss + 5 很给力!

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2023-11-22 15:32:42 | 显示全部楼层
szwp 发表于 2023-11-22 15:15
ChiShingChan在论坛的,可以用VBS来完成这个题目。

原需求就是来自于论坛这个代码插件不能使用,试了多个浏览器都没搞定……
图片能上传却不能上传txt是何解?

2023-11-22_152924.jpg



点评

1,插件问题修复了flash仍是不行,不折腾插件了。 2,搜索了一下发现能传图片不能传txt等等是论坛规则调整,需要更高会员级别了。  发表于 2023-11-22 16:45
这个功能需要flash  详情 回复 发表于 2023-11-22 15:34
回复

使用道具 举报

发表于 2023-11-22 15:34:39 | 显示全部楼层
nfans 发表于 2023-11-22 15:32
原需求就是来自于论坛这个代码插件不能使用,试了多个浏览器都没搞定……
图片能上传却不能上传txt是何 ...

这个功能需要flash

点评

啊,感谢!我试试  发表于 2023-11-22 15:42
回复

使用道具 举报

 楼主| 发表于 2023-11-22 15:39:54 | 显示全部楼层
newyun 发表于 2023-11-22 15:28
@echo off
setlocal enabledelayedexpansion

是删所有行行首,并保留空格,请注意审题,所以结果还不正确

空格与空行别弄混了

点评

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}\\.\root\cimv2") Set colItems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem") For Each objItem in colItems  详情 回复 发表于 2023-11-22 15:42
回复

使用道具 举报

发表于 2023-11-22 15:42:25 | 显示全部楼层
nfans 发表于 2023-11-22 15:39
是删所有行行首,并保留空格,请注意审题,所以结果还不正确

空格与空行别弄混了

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
For Each objItem in colItems
OSA = objItem.OSArchitecture
Next
Const HKLM = &H80000002
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}StdRegProv")
If OSA = "64-bit" Then
oReg.GetStringValue HKLM,"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\XReplace","UninstallString",UninstallString
If Not IsNull(UninstallString) Then InstallLocation = Replace(UninstallString,"uninstall","XReplace")
Else
oReg.GetStringValue HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XReplace","UninstallString",UninstallString
If Not IsNull(UninstallString) Then InstallLocation = Replace(UninstallString,"uninstall","XReplace")
End If
Set WshShell = WScript.CreateObject("WScript.Shell")
If IsNull(InstallLocation) Then
WshShell.Popup "杞欢鏈畨瑁咃紒", 5, "閿欒", 0
WScript.Quit
End If
Name = Array("XReplace.exe")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,(Debug)}\\.\root\cimv2")
Set colProcessList = objWMIService.ExecQuery ("Select * from Win32_Process")
For Each objProcess In colProcessList
For Each Process In Name
If LCase(objProcess.Name) = LCase(Process) Then
objProcess.Terminate()
End If
Next
Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(InstallLocation) Then
Set ado_stream = CreateObject("ADODB.Stream")
ado_stream.Type = 1
ado_stream.open
ado_stream.LoadFromFile InstallLocation
ado_stream.position = 215133
ado_stream.Write HexToByte("E9B701000090")
ado_stream.position = 256771
ado_stream.Write HexToByte("E9CE02000090")
ado_stream.position = 277094
ado_stream.Write HexToByte("01")
ado_stream.position = 313599
ado_stream.Write HexToByte("B80100")
ado_stream.position = 313855
ado_stream.Write HexToByte("B80100")
ado_stream.position = 314442
ado_stream.Write HexToByte("B80100")
ado_stream.position = 314901
ado_stream.Write HexToByte("B80100")
ado_stream.SaveToFile InstallLocation, 2
ado_stream.Close
Set ado_stream = Nothing
End If
WshShell.Popup "瓒呯骇瀛楃涓叉壒閲忔浛鎹㈠伐鍏?v4.2.5 鐮磋В琛ヤ竵" & vbnewline & vbnewline & "鍒朵綔锛欳hiShingChan  缂栫▼璇█锛歏BScript",10,"瀹屾垚",0
Function HexToByte(hexStr)
Set xmldom = Wscript.CreateObject("Microsoft.XMLDOM")
Set byteObj= xmldom.createElement("byteObj")
byteObj.dataType = "bin.hex"
byteObj.nodeTypedValue = hexStr
HexToByte=byteObj.nodeTypedValue
End Function
这是 测试过来的结果,会把空行也处理掉,我想不出更好的办法了。我没转成ANSI所以中文乱码了。你注意下就行了

点评

先用findstr /n给原文件加行号,再去掉,就能留空行了。 在9楼基础上改改试试。  详情 回复 发表于 2023-11-22 15:49
回复

使用道具 举报

发表于 2023-11-22 15:49:05 | 显示全部楼层
newyun 发表于 2023-11-22 15:42
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}\\.\root\cimv2")
Set col ...

先用findstr /n给原文件加行号,再去掉,就能留空行了。
在9楼基础上改改试试。
回复

使用道具 举报

发表于 2023-11-22 15:55:24 | 显示全部楼层
学习学习
回复

使用道具 举报

发表于 2023-11-22 15:57:26 | 显示全部楼层
高手如云
回复

使用道具 举报

发表于 2023-11-22 16:01:16 | 显示全部楼层
你代码的第三行,改成
  1. (for /f "tokens=1* delims=:" %%h in ('findstr /n .* %fn%')do (
复制代码
回复

使用道具 举报

发表于 2023-11-22 16:07:10 | 显示全部楼层
楼上已有最佳答案
  1. @echo off&setlocal enabledelayedexpansion
  2. ::删所有行首4字符并保留其它空行到b.txt
  3. (for /f "delims=" %%i in ('findstr /n .* a.txt')do set "t=%%i"&echo=!t:~6!)>b.txt
  4. pause
复制代码
回复

使用道具 举报

 楼主| 发表于 2023-11-22 16:27:19 | 显示全部楼层
感谢各位朋友热心帮助测试,综合使用9、17、18楼代码仍有明显bug,有条件请用 Beyond Compare 比对测试。
回复

使用道具 举报

发表于 2023-11-22 17:16:45 | 显示全部楼层
  1. @echo off
  2. ::删所有行首4字符并保留其它空行到b.txt
  3. (for /f "delims=" %%i in ('findstr /n .* a.txt')do (
  4.         set "t=%%i"
  5.     setlocal enabledelayedexpansion
  6.     set x=!t:*:=!
  7.         echo=!t:~6!
  8.     endlocal
  9. ))>"b.txt"
  10. pause
复制代码

点评

报告各位大佬,目标越来越接近,此处从11行起开始原本对齐的变得没对齐了 [attachimg]534776[/attachimg]  详情 回复 发表于 2023-11-22 17:31
回复

使用道具 举报

 楼主| 发表于 2023-11-22 17:31:04 | 显示全部楼层

报告各位大佬,目标越来越接近,此处从11行起开始原本对齐的变得没对齐了
20.jpg

回复

使用道具 举报

发表于 2023-11-22 17:37:04 | 显示全部楼层
vscode打开
选中那几行,shift+Tab,搞定!

点评

百度 VBS代码在线格式化美化工具 就搞定了,bat太费劲了  详情 回复 发表于 2023-11-24 20:17
回复

使用道具 举报

发表于 2023-11-22 17:43:56 | 显示全部楼层
nfans 发表于 2023-11-22 17:31
报告各位大佬,目标越来越接近,此处从11行起开始原本对齐的变得没对齐了

你原文本就多空格

点评

a.txt红色竖线前面4个空格,处理后的b.txt前几行处理是正确的,后面还剩余一个空格, 刚复制下来才发现论坛代码控件会自动给粘贴的内容行首增加4个空格 另外,这个批处理对空行保留的处理是否具有通用性?如果是  详情 回复 发表于 2023-11-23 09:59
回复

使用道具 举报

发表于 2023-11-22 17:54:06 | 显示全部楼层
进来学习
回复

使用道具 举报

发表于 2023-11-23 00:54:49 | 显示全部楼层
观摩学习,感谢各位大佬解题!
我其实也有个想要的功能,就是删除所有空行(非空格),一直没研究成功。
回复

使用道具 举报

发表于 2023-11-23 07:55:51 | 显示全部楼层
折腾啥。
windows 处理空行和换行都麻烦。

正则 "^    " 替换成 ""  不就行了。

回复

使用道具 举报

发表于 2023-11-23 09:16:54 | 显示全部楼层
如果接受第3方工具sed(下载: http://bcn.bathome.net/tool/4.9/sed.exe )就比较简单(空格数,下例为{4},可根据需要修改):
sed -r -i.bak "s/^ {4}//" a.txt

评分

参与人数 1无忧币 +5 收起 理由
nfans + 5 很给力! 超牛,输出结果完美!

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2023-11-23 09:59:33 | 显示全部楼层
Zap 发表于 2023-11-22 17:43
你原文本就多空格

a.txt红色竖线前面4个空格,处理后的b.txt前几行处理是正确的,后面还剩余一个空格,

PS: 论坛代码控件会自动给粘贴的内容行首增加4个空格
另外,这个批处理对空行保留的处理是否具有通用性?如果是指定行处理那不如用27楼朋友提到的方法处理了,当然也欢迎愿意研究批处理的朋友继续。

20.jpg
回复

使用道具 举报

发表于 2023-11-23 10:39:02 | 显示全部楼层

点评

是的,当是随便从论坛扒了一个代码复制出来  详情 回复 发表于 2023-11-23 10:57
回复

使用道具 举报

 楼主| 发表于 2023-11-23 10:57:12 | 显示全部楼层
szwp 发表于 2023-11-23 10:39
http://bbs.wuyou.net/forum.php?mod=redirect&goto=findpost&ptid=420811&pid=4075512&fromuid=225195

...

是的,当是随便从论坛扒了一个代码复制出来
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-6-25 00:17

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表