欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

bat實現(xiàn)刪除文本中的空行、空格、制表符、最后一行空行

 更新時間:2024年02月23日 10:38:43   作者:小青龍  
本文主要介紹了 bat實現(xiàn)刪除文本中的空行、空格、制表符、最后一行空行

這篇文章將演示 bat批處理如何刪除文件中空白行、空格、制表符

一、準備測試數(shù)據(jù)

準備一個old_file.txt文件,UTF-8編碼,內(nèi)容如下:

first line
second line    
    third line    

	forth line		
	    
	fifth line    
		
    sixth line	  
    	
	測試  1  	
        
    測試	2   
Finish      

Notepad++中,顯示所有字符,截圖看下

old_file.txt

二、通過for /f實現(xiàn)

1. 刪除僅含換行符的空行

Windows系統(tǒng)下CR LF表示換行符

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

Tips:

  • echo.%%l>>,.不能省略,%%l>>之間不能有空格,不然空格會在新結(jié)果中出現(xiàn);
  • echo.你可以替換成echo+、echo;、echo: 等等,關(guān)于echo這種用法的更多討論可參考:ECHO. FAILS to give text or blank line - Instead use ECHO/

執(zhí)行結(jié)果:
新舊文本對比(肉眼對比),可以看出第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:

  • set "str1=!str: = !",注意這里的被替換字符是一個制表符,將制表符替換為空格(嘗試了將制表符替換為空,會出現(xiàn)第8行兩個指標符的行仍原樣輸出了。。。不知道為啥);
  • set "str2=!str1: =!",將空格替換為空;

經(jīng)過上邊兩次替換,如果仍不為空,則表示該行為非空白行,然后 echo.%%L輸出原行內(nèi)容

執(zhí)行結(jié)果:
新舊文本對比,可以看出僅含換行符、僅含空格或指標符的空白行(第4、6、8、10、12行)去除了。

刪除所有空白行

3. 刪除所有空白行以及非空白行左側(cè)的空格和制表符

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

Tips:

  • if not "%%L"=="" echo.%%L如果換成echo.%%L,則僅含空格或制表符的行,將輸出為僅含換行符的空行。

執(zhí)行結(jié)果:
新舊文本對比,可以看出所有空白行及非空白行左側(cè)的空格或制表符都去掉了

刪除空白行及左側(cè)空白

4. 刪除所有空白行以及非空白行兩側(cè)的空格和制表符

@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:

  • 定義了一個rdel函數(shù),用來去除非空白行右側(cè)的空格和制表符(為什么未寫去除左側(cè)的空格和制表符,因為for /F "tokens=*"已經(jīng)把左側(cè)的去除了)

執(zhí)行結(jié)果:
新舊文本對比,可以看出所有空白行、非空白行兩側(cè)的空格和制表符都去掉了,中間的空格和制表符仍保留

刪除空白行及非空白行兩側(cè)的空格和制表符

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:

  • 其實就是將【2. 刪除所有空白行】的代碼中echo.%%L換成了echo.!str2!

執(zhí)行結(jié)果:
新舊文本對比,可以看出所有空白行、所有空格和制表符(包括文字中間的)都去掉了

刪除文中所有空白行及所有空格和制表符

三、通過findstr實現(xiàn)

1. 刪除僅含換行符的空行

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

Tips:

  • /v 僅打印不包含匹配項的行;
  • /r 將搜索字符串作為一般表達式使用;

一般表達式快速參考:

表達式解釋說明
.通配符: 任何字符
*重復(fù): 以前字符或類出現(xiàn)零或零以上次數(shù)
^行位置: 行的開始
$行位置: 行的終點
[class]字符類: 任何在字符集中的字符
[^class]補字符類: 任何不在字符集中的字符
[x-y]范圍: 在指定范圍內(nèi)的任何字符
\xEscape: 元字符 x 的文字用法
\<xyz字位置: 字的開始
xyz\>字位置: 字的結(jié)束
  • /c:string 使用指定字符串作為文字搜索字符串
  • findstr . 表示包含任何字符的行,因此除第4行,其余都滿足

執(zhí)行結(jié)果:
新舊文本對比,可以看出第4行僅含換行符的空白行被去除了

findstr刪除空行

2. 刪除所有空白行

刪除僅含換行符、僅含空格或制表符的空白行

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

Tips:

  • "^[ ]*$" 的[]內(nèi)是<space> <tab>兩個字符,這個表達式的意思是:從行首到行尾,僅有0個或多個空格或制表符;

執(zhí)行結(jié)果:
新舊文本對比,可以看出僅含換行符、僅含空格或指標符的空白行(第4、6、8、10、12行)去除了。

刪除所有空白行

無法通過 findstr 的方式,實現(xiàn)刪除非空白行兩側(cè)的空格和制表符

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

我這里有個需求將old_file.txt文件中僅含換行符的空行及最后一行去掉,文件內(nèi)容如下
(這里只給截圖,準備數(shù)據(jù)里有,只是最后一行有區(qū)別)

在這里插入圖片描述

然后你再使用【二、通過for /f實現(xiàn)】中的批處理腳本處理修改后的old_file.txt文件,你會發(fā)現(xiàn)新生成的文件Finish....后邊始終會多出來一個CR LF換行符,其實這是因為 echo在輸出內(nèi)容時會自動在行尾尾隨一個CR LF,大多數(shù)情況下這也沒啥影響,但假如(無論原文件中是否有最后一行空行)你就想在新生成的文件中去掉它,該如何處理呢?

嘗試了幾種方法,總結(jié)如下:

1. 使用set /p=實現(xiàn)

代碼來源: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 

執(zhí)行結(jié)果:
新舊文本對比,你會發(fā)現(xiàn),最后一行不再有CR LF,但是每行的開頭的空格或制表符也一并給去掉了。但我這個腳本最初的意圖刪除僅含換行符的空行以及最后一行空行。

這是因為set /p =會使 前導(dǎo)引號空格剝離,前導(dǎo)=報錯語法錯誤,在不同的Windows版本之間限制會有不同,有關(guān)詳細討論參見:
SET /P prompt mechanics - New behavior: = makes syntax error

刪除效果

2. 使用backspace回退字符實現(xiàn)

為了解決set /p=導(dǎo)致的,前導(dǎo)空格或制表符剝離的問題,有大神提出了,使用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窗口的輸出效果

對比結(jié)果

對比原文本可以看出,對于tab制表符作為前導(dǎo)的行,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 

看下輸出結(jié)果對比,可以發(fā)現(xiàn)backspace回退字符,在重定向到文件后,完全無效,+未被回退,還多出來一個BS字符

輸出結(jié)果對比

我也嘗試了

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

參考:
?是一個backspace字符,在不同的CodePage下可能顯示不同,測試效果同上,也僅在dos窗口上有效,重定向到文件后無效,這里不再演示了

3. 使用echo+set /p=實現(xiàn)

@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:

  • for /f部分使用echo輸出除最后一行外的內(nèi)容,echo.|set /p部分負責輸出最后一行,set /p抑制了最后一行尾隨的換行符,所以最后不會出現(xiàn)一個空行。

執(zhí)行結(jié)果:
可以發(fā)現(xiàn),已經(jīng)能滿足我的使用場景:刪除僅含換行符的空行以及最后一行空行

結(jié)果對比

4. 使用prompt+cmd /d /k <nul實現(xiàn)

然后我又在 Output text without linefeed, even with leading space or = 評論區(qū)里看到了jeb大神給出的set "prompt=[promptString]"+cmd /d /k < nul的方案。
不過這里的promptString最長為511字符,你也可以到這里看相關(guān)說明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
	)
)

執(zhí)行結(jié)果:
可以發(fā)現(xiàn),已經(jīng)能滿足我的使用場景:刪除僅含換行符的空行以及最后一行空行

執(zhí)行結(jié)果對比

五、總結(jié)

  • 【四、刪除文件最后一行空行】中 1、2 都不滿足我的需求;3、4 可以滿足我的需求;當然使用batch實現(xiàn)刪除文件最后一行空行的方式肯定還有,文末列出的參考資料里也有很多其他方案可供參考,也建議仔細閱讀,相信你會有不少收獲。
  • findstr實現(xiàn)的【1. 刪除僅含換行符的空行】【2. 刪除所有空白行】從效率和安全性上都比for /f實現(xiàn)的要好很多。

參考資料:

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?

到此這篇關(guān)于 bat實現(xiàn)刪除文本中的空行、空格、制表符、最后一行空行的文章就介紹到這了,更多相關(guān) bat 刪除空行空格內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論