Windows bat实现删除文本中的 空行、空格、制表符、最后一行空行

news2025/1/11 5:39:36

文章目录

    • 一、准备测试数据
    • 二、通过`for /f`实现
      • 1. 删除仅含换行符的空行
      • 2. 删除所有空白行
      • 3. 删除所有空白行以及非空白行左侧的空格和制表符
      • 4. 删除所有空白行以及非空白行两侧的空格和制表符
      • 5. 删除所有空白行以及所有空格和制表符
    • 三、通过`findstr`实现
      • 1. 删除仅含换行符的空行
      • 2. 删除所有空白行
    • 四、删除文件最后一行空行
      • 1. 使用`set /p=`实现
      • 2. 使用`backspace`回退字符实现
      • 3. 使用`echo`+`set /p=`实现
      • 4. 使用`prompt`+`cmd /d /k <nul`实现
    • 五、总结

这篇文章将演示 bat批处理如何删除文件中空白行、空格、制表符

一、准备测试数据

准备一个old_file.txt文件,UTF-8编码,内容如下:

first line
second line    
    third line    

	forth line		
	    
	fifth line    
		
    sixth line	  
    	
	测试  1  	
        
    测试	2   
Finish      

Notepad++中,显示所有字符,截图看下
old_file.txt

二、通过for /f实现

1. 删除仅含换行符的空行

Windows系统下CR LF表示换行符

@echo off
for /F "delims=" %%l in (old_file.txt) do (
	echo.%%l>>new_file1.txt
)

Tips:

  1. echo.%%l>>,.不能省略,%%l>>之间不能有空格,不然空格会在新结果中出现;
  2. echo.你可以替换成echo+echo;echo: 等等,关于echo这种用法的更多讨论可参考:ECHO. FAILS to give text or blank line - Instead use ECHO/

执行结果:
新旧文本对比(肉眼对比),可以看出第4行仅含换行符的空白行被去除了。
注意:最后一行不含任何字符的保持原样
新旧文本对比

2. 删除所有空白行

删除仅含换行符、仅含空格或制表符的空白行

@echo off
setlocal enabledelayedexpansion
for /F "delims=" %%L in (old_file.txt) do (
	set "str=%%L"
	set "str1=!str:	= !"
	set "str2=!str1: =!"
	if not "!str2!"=="" echo.%%L
)>>new_file2.txt
endlocal

Tips:

  1. set "str1=!str: = !",注意这里的被替换字符是一个制表符,将制表符替换为空格(尝试了将制表符替换为空,会出现第8行两个指标符的行仍原样输出了。。。不知道为啥);
  2. set "str2=!str1: =!",将空格替换为空;
  3. 经过上边两次替换,如果仍不为空,则表示该行为非空白行,然后 echo.%%L输出原行内容

执行结果:
新旧文本对比,可以看出仅含换行符、仅含空格或指标符的空白行(第4、6、8、10、12行)去除了。
删除所有空白行

3. 删除所有空白行以及非空白行左侧的空格和制表符

@echo off
for /F "tokens=*" %%L in (old_file.txt) do (
	if not "%%L"=="" echo.%%L
)>>new_file3.txt

Tips:

  1. if not "%%L"=="" echo.%%L如果换成echo.%%L,则仅含空格或制表符的行,将输出为仅含换行符的空行。

执行结果:
新旧文本对比,可以看出所有空白行及非空白行左侧的空格或制表符都去掉了删除空白行及左侧空白

4. 删除所有空白行以及非空白行两侧的空格和制表符

@echo off
setlocal enabledelayedexpansion
for /F "tokens=*" %%L in (old_file.txt) do (
	set "str=%%L"
	call :rdel
	if not "!str!"=="" echo !str!>>new_file4.txt
)
endlocal
goto :eof

:rdel
	set tmp=%str%
	:sloop
		if "%tmp%"=="" goto eloop
		if "%tmp:~-1%"==" " (
			set "tmp=%tmp:~0,-1%"
			goto sloop
		)
		if "%tmp:~-1%"=="	" (
			set "tmp=%tmp:~0,-1%"
			goto sloop
		)
	:eloop
	set "str=%tmp%"
goto :eof

Tips:

  1. 定义了一个rdel函数,用来去除非空白行右侧的空格和制表符(为什么未写去除左侧的空格和制表符,因为for /F "tokens=*"已经把左侧的去除了)

执行结果:
新旧文本对比,可以看出所有空白行、非空白行两侧的空格和制表符都去掉了,中间的空格和制表符仍保留
删除空白行及非空白行两侧的空格和制表符

5. 删除所有空白行以及所有空格和制表符

@echo off
setlocal enabledelayedexpansion
for /F "delims=" %%L in (old_file.txt) do (
	set "str=%%L"
	set "str1=!str:	= !"
	set "str2=!str1: =!"
	if not "!str2!"=="" echo.!str2!
)>>new_file5.txt
endlocal

Tips:

  1. 其实就是将【2. 删除所有空白行】的代码中echo.%%L换成了echo.!str2!

执行结果:
新旧文本对比,可以看出所有空白行、所有空格和制表符(包括文字中间的)都去掉了
删除文中所有空白行及所有空格和制表符

三、通过findstr实现

1. 删除仅含换行符的空行

@echo off
findstr /v /r /c:"^$" old_file.txt > new_file6.txt
::或者
::findstr . old_file.txt > new_file6.txt

Tips:

  1. /v 仅打印不包含匹配项的行;
  2. /r 将搜索字符串作为一般表达式使用;
    一般表达式快速参考:
表达式解释说明
.通配符: 任何字符
*重复: 以前字符或类出现零或零以上次数
^行位置: 行的开始
$行位置: 行的终点
[class]字符类: 任何在字符集中的字符
[^class]补字符类: 任何不在字符集中的字符
[x-y]范围: 在指定范围内的任何字符
\xEscape: 元字符 x 的文字用法
\<xyz字位置: 字的开始
xyz\>字位置: 字的结束
  1. /c:string 使用指定字符串作为文字搜索字符串
  2. findstr . 表示包含任何字符的行,因此除第4行,其余都满足

执行结果:
新旧文本对比,可以看出第4行仅含换行符的空白行被去除了
findstr删除空行

2. 删除所有空白行

删除仅含换行符、仅含空格或制表符的空白行

@echo off
findstr /v /r /c:"^[ 	]*$" old_file.txt >new_file7.txt

Tips:

  1. "^[ ]*$"[]内是<space> <tab>两个字符,这个表达式的意思是:从行首到行尾,仅有0个或多个空格或制表符;

执行结果:
新旧文本对比,可以看出仅含换行符、仅含空格或指标符的空白行(第4、6、8、10、12行)去除了。
删除所有空白行

无法通过 findstr 的方式,实现删除非空白行两侧的空格和制表符

四、删除文件最后一行空行

我这里有个需求将old_file.txt文件中仅含换行符的空行及最后一行去掉,文件内容如下
(这里只给截图,准备数据里有,只是最后一行有区别)
在这里插入图片描述
然后你再使用【二、通过for /f实现】中的批处理脚本处理修改后的old_file.txt文件,你会发现新生成的文件Finish....后边始终会多出来一个CR LF换行符,其实这是因为 echo在输出内容时会自动在行尾尾随一个CR LF,大多数情况下这也没啥影响,但假如(无论原文件中是否有最后一行空行)你就想在新生成的文件中去掉它,该如何处理呢?

尝试了几种方法,总结如下:

1. 使用set /p=实现

代码来源:batfile - how to remove the last, empty, line in a file?

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

set "FLAG=" 
> "new_file.txt" (
    for /F "usebackq delims=" %%L in ("old_file.txt") do (
     if defined FLAG echo.
     ::echo.|set /P "dummyName=%%L"
     < nul set /P "dummyName=%%L"
     set "FLAG=#"
    ) 
) 

endlocal 
exit /B 

执行结果:
新旧文本对比,你会发现,最后一行不再有CR LF,但是每行的开头的空格或制表符也一并给去掉了。但我这个脚本最初的意图删除仅含换行符的空行以及最后一行空行。

这是因为set /p =会使 前导引号空格剥离,前导=报错语法错误,在不同的Windows版本之间限制会有不同,有关详细讨论参见:
SET /P prompt mechanics - New behavior: = makes syntax error
删除效果

2. 使用backspace回退字符实现

为了解决set /p=导致的,前导空格或制表符剥离的问题,有大神提出了,使用backspace回退字符的方案

@echo off
chcp 65001 & cls
setlocal EnableExtensions DisableDelayedExpansion 
::获取回退字符并存储到bs变量
for /F %%a in ('"prompt $H & for %%b in (1) do rem"') do (set "bs=%%a")
::处理文本
set "FLAG=" 
(
	for /F "usebackq delims=" %%L in ("old_file.txt") do (
		if defined FLAG echo.
		< nul set /P "dummyName=+%bs%%%L"
		set "FLAG=#"
	)
)
endlocal 
pause >nul

上边代码仅输出到dos窗口,先来看下在dos窗口的输出效果
对比结果
对比原文本可以看出,对于tab制表符作为前导的行,backspace并未生效,其余的生效了。

然后代码做下改动,输出到new_file.txt文件,看下效果。

@echo off
setlocal EnableExtensions DisableDelayedExpansion 
::获取回退字符并存储到bs变量
for /F %%a in ('"prompt $H & for %%b in (1) do rem"') do (set "bs=%%a")
::处理文本
set "FLAG=" 
> "new_file.txt" (
	for /F "usebackq delims=" %%L in ("old_file.txt") do (
		if defined FLAG echo.
		< nul set /P "dummyName=.%bs%%%L"
		set "FLAG=#"
	)
)
endlocal 
exit /B 

看下输出结果对比,可以发现backspace回退字符,在重定向到文件后,完全无效,+未被回退,还多出来一个BS字符
输出结果对比
我也尝试了

<nul set /p "_s=.◘%%L"

参考:
是一个backspace字符,在不同的CodePage下可能显示不同,测试效果同上,也仅在dos窗口上有效,重定向到文件后无效,这里不再演示了

3. 使用echo+set /p=实现

参考 使用批处理从文本文件中删除最后一行(包括空行),我针对我的场景,进行了优化代码如下:

@echo off
for /F "delims=" %%L in (old_file.txt) do (
	setlocal enabledelayedexpansion
	if defined row echo.!row!
	endlocal
	set row=%%L
)>>new_file1.txt
echo.|set /p "=%row%" >>new_file1.txt

Tips:

  1. for /f部分使用echo输出除最后一行外的内容,echo.|set /p部分负责输出最后一行,set /p抑制了最后一行尾随的换行符,所以最后不会出现一个空行。

执行结果:
可以发现,已经能满足我的使用场景:删除仅含换行符的空行以及最后一行空行
结果对比

4. 使用prompt+cmd /d /k <nul实现

然后我又在 Output text without linefeed, even with leading space or = 评论区里看到了jeb大神给出的set "prompt=[promptString]"+cmd /d /k < nul的方案。
不过这里的promptString最长为511字符,你也可以到这里看相关说明How do I add a space on this line?

@echo off
set flag=
> new_file.txt (
	for /F "delims=" %%L in (old_file.txt) do (
		setlocal
		if defined flag echo.
		set "prompt=%%L"
		cmd /d /k < nul
		endlocal
		set flag=T
	)
)

执行结果:
可以发现,已经能满足我的使用场景:删除仅含换行符的空行以及最后一行空行
执行结果对比

五、总结

  1. 【四、删除文件最后一行空行】中 1、2 都不满足我的需求;3、4 可以满足我的需求;当然使用batch实现删除文件最后一行空行的方式肯定还有,文末列出的参考资料里也有很多其他方案可供参考,也建议仔细阅读,相信你会有不少收获。
  2. findstr实现的【1. 删除仅含换行符的空行】【2. 删除所有空白行】从效率和安全性上都比for /f实现的要好很多。


参考资料:
Windows Batch: How remove all blank (or empty) lines
Batch: remove all white spaces from a text file?
batfile - how to remove the last, empty, line in a file?
Windows batch: echo without new line
Output text without linefeed, even with leading space or =
How do I add a space on this line?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/751890.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Base64存储为文件

要将Base64编码的字符串存储为文件&#xff0c;您可以按照以下步骤进行操作&#xff1a; 将Base64编码的字符串解码为字节数组。您可以使用Java的Base64类进行解码&#xff0c;例如&#xff1a; import java.util.Base64;String base64String "your_base64_encoded_str…

unity 打包htv vive 客户端包,调不出SteamVR

原因一&#xff1a; 引用自&#xff1a;unity 运行包无法连接SteamVR问题_野区捕龙为宠的博客-CSDN博客 原因二&#xff1a; 1、打包出来的exe文件命名是中文名&#xff0c;如&#xff1a;危化品.exe 2、打包路径中有中文。 避免以上情况即可。 引用自&#xff1a;unity 打包…

算法训练营第三十八天||● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

● 理论基础 五步走&#xff1a; 确定dp数组 递推公式 dp数组初始化 遍历顺序 打印dp数组 ● 509. 斐波那契数 这道题比较简单&#xff0c;但自己不看答案还做不出来&#xff0c;没想到用初始的方法 先看递归 只需要两行代码 确定终止条件 和逻辑 class Solution { p…

Java-API简析_java.lang.Process类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131714752 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

软考A计划-系统集成项目管理工程师--项目质量管理-尾

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

【FAQ】API6低代码开发问题汇总

参考文档&#xff1a; 低代码开发参考文档&#xff1a; 文档中心:使用低代码进行开发 基于景区模板开发元服务&#xff1a; 文档中心:模板简介 使用API6低代码开发遇到的问题汇总情况如下&#xff1a; 1、低代码环境下&#xff0c;如何实现box-shadow阴影效果的配置&#…

第五章:DeepLabV1——深度卷积神经网络和全连接条件随机场的语义图像分割

0.摘要 深度卷积神经网络&#xff08;DCNN&#xff09;在图像分类和目标检测等高级视觉任务中表现出最先进的性能。本研究结合了DCNN和概率图模型的方法&#xff0c;用于解决像素级分类的任务&#xff08;也称为“语义图像分割”&#xff09;。我们发现&#xff0c;DCNN最后一层…

sping boot与JPA结合使用

1、pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http:/…

SOPC之NiosⅡ系统(二)

常用NIOS Ⅱ组件概括 目录 1.时钟组件 2.Nios Ⅱ处理器 2.1 Main 2.2 Vector 2.3 Caches and Memory Interfaces 2.4 Arithmetic Instructions 2.5 JTAG Debug 3.RAM组件 4.System ID组件 5.JTAG UART组件 6.PIO组件 6.1 基础设置(Basic Settings) 6.2 输出寄存器…

应用于智能眼镜上实现检测功能的距离传感芯片

随着智能穿戴设备的发展&#xff0c;各种新型的电子产品不断被研发出来&#xff0c;诸如智能头盔、智能手表、智能手环等等&#xff0c;智能眼镜就是其中一种&#xff0c;国内华为、小米相继推出智能产品。 智能眼镜具有和智能耳机相似的功能&#xff0c;不仅保留眼镜本身功能…

Twitter迎来史上最大危机,超级App能成为其救命武器吗?

前段时间闹得沸沸扬扬的“马扎大战”再出新剧情&#xff0c;继“笼斗”约架被马斯克妈妈及时叫停之后&#xff0c;马斯克在7月9日再次向扎克伯克打起嘴炮&#xff0c;这次不仅怒骂小扎是混蛋&#xff0c;还要公开和他比大小&#xff1f;&#xff01;&#xff01;此番马斯克的疯…

应用开发环境搭建

应用开发环境搭建 1、安装JDK linux上传安装包解压缩设置环境变量判断JDK是否安装成功 2、nginx下载选择Stable version版本下载到本地&#xff08;该版本为Linux版本&#xff09;&#xff0c;下载完成后直接在本地解压后放入linux系统中下载完成后&#xff0c;安装Nginx&#…

android studio 使用lib中的framework.jar编译

本文参考了网上搜索到的内容总结了一下&#xff0c;感谢大神们的无私奉献。 在App中的build.gradle中的android{}下添加&#xff1a; android{...gradle.projectsEvaluated {tasks.withType(JavaCompile) {Set<File> fileSet options.bootstrapClasspath.getFiles()Li…

想知道音频转文字怎么弄吗?看完这篇文章你就懂了

小伙伴们&#xff0c;你们有没有遇到过这样的情况&#xff1a;听到了一段有趣或重要的音频&#xff0c;但却无法方便地保存下来或与他人分享&#xff1f;别担心&#xff0c;现在有很多免费的音频转文字软件app可以帮助我们解决这个问题。不过&#xff0c;这些音频转文字软件app…

S32K系列MCU介绍和资料搜集

1. S32K系列微控制器概述 S32K系列微控制器&#xff0c;是NXP推出的专门面向汽车电子和工业应用场合的微控制器。基于ArmCortex-M系列的可扩展、低功耗微控制器&#xff0c;获得了AEC-Q100认证&#xff0c;具有高级功能安全、信息安全和软件支持&#xff0c;适用于工业和汽车A…

进程间通信之匿名管道(pipe)

文章目录 前言管道管道的创建管道的使用单进程使用管道进行通信多进程使用管道进行通信关闭管道的读端/写端 总结 前言 管道分为匿名管道和命名管道&#xff0c;匿名管道只能在有共同祖先的(有亲缘关系)进程中使用&#xff0c;而命名管道可以在任意进程中使用&#xff0c;以下…

【youcans动手学模型】目标检测之 OverFeat 模型

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】目标检测之 OverFeat 模型 1. OverFeat 卷积神经网络模型1.1 论文摘要1.2 技术背景1.3 基本方法模型设计多尺度分类滑动窗口&#xff08;Sliding window&#xff09;定位&#…

ACL—访问控制列表

目录 ACL的分类&#xff1a; 配置 配置基础ACL &#xff1a; 例一&#xff1a; 例二&#xff1a; 配置高级ACL &#xff1a; 例一&#xff1a; 例二&#xff1a; ACL—访问控制列表 配置了ACL的网络设备根据事先制定号的规则&#xff0c;然后对经过该设备的流量按照对应的规…

访问者模式:灵活处理对象结构

访问者模式&#xff1a;灵活处理对象结构 在软件开发中&#xff0c;我们经常会遇到处理复杂对象结构的情况。对象结构由多个不同类型的对象组成&#xff0c;而每个对象都可能具有不同的行为。此时&#xff0c;访问者模式可以派上用场。访问者模式是一种行为设计模式&#xff0…

接口的幂等性如何设计

前言 所谓幂等: 多次调用方法或者接口不会改变业务状态&#xff0c;可以保证重复调用的结果和单次调用的结果一致。 我们在开发中主要操作也就是CURD,其中读取操作和删除操作是天然幂等的&#xff0c;我们所关心的就是创建操作、更新操作。 创建操作一定是非幂等的因为要涉及…