2013-04-22 59 views
2

我有一个大的文本文件(约30,000行长),我需要删除(行号5-30)的一系列行,这可能使用批处理?批处理 - 删除行的范围

非常感谢

+0

你可能会在“纯批量”中做到这一点,但你最好使用@ foxidrive的建议。批处理在这种情况下非常缓慢。 – Endoro 2013-04-22 10:32:25

+0

@Endoro这太相对了,FOR命令不需要处理文件的所有内容,您可以从第5行开始,并停止从第30行退出For。 – ElektroStudios 2013-04-22 10:54:32

+0

不好意思。我将这个主题理解为“从大文件中删除第5至30行并返回其余部分”。如果我想要从5到30的26行,我会用“Extract range of lines”代替。我错了吗?对不起,英文不是我的母语,所以也许这一点是一个惯用的细节... – Aacini 2013-04-22 22:25:22

回答

0

如果你愿意,你可以用我的例行这是很容易为书面方式一个命令的简单方法:

Call :TEXTMAN SR RANGE_A RANGE_B "Test.txt" 

PS:我添加了GetRange功能为你:)

编辑:测试与300.000行文本文件,不到一秒钟,以得到结果。

UPDATE 2

现在它接受空行,除非C + C-功能。

TextMan.bat

@Echo OFF 


:: TEXT MANIPULATOR ROUTINE v0.5 
:: by Elektro [email protected] 


REM SYNTAX: 
:: 
:: TEXTMAN [ACTION] [LINE(S)] [FILE] [TEXT] 
:: 
:: * [LINE(S)] parameter is Optional for some actions 
:: * [TEXT] parameter is Optional for some actions 


REM ACTIONS: 
:: 
:: AB = ADD_BEGINNING  * Add text to the beginning of a line. 
:: AE = ADD_ENDING   * Add text to the end of a line. 
:: E = ERASE    * Delete a line. 
:: I = INSERT    * Add a empty line (Or a line with text). 
:: RL = REPLACE_LINE  * Replace a entire line. 
:: RS = REPLACE_STRING  * Replace word from line. 
:: RSA = REPLACE_STRING_ALL * Replace word from all lines. 
:: C+ = CHARACTER_PLUS  * Delete the first "X" characters from all lines. 
:: C- = CHARACTER_LESS  * Delete the last "X" characters from all lines. 
:: L+ = LINE_PLUS   * Cut the first "X" amount of lines. 
:: L- = LINE_LESS   * Cut the last "X" amount of lines. 
:: GL = GET_LINE   * Delete all except "X" line. 
:: GR = GET_RANGE   * Delete all except "X" range of lines. 


REM EXAMPLES: 
:: 
:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 
::                   :: 
:: Delete the line 3              :: 
:: Call :TEXTMAN E 3 "Test.txt"           :: 
::                   ::                   
:: Add a string to the beginning of line 3         :: 
:: Call :TEXTMAN AL 3 "Test.txt" "Elektro [email protected]"       :: 
::                   ::                  
:: Add a string to the end of line 3.          :: 
:: Call :TEXTMAN AR 3 "Test.txt" "Elektro [email protected]"       :: 
::                   ::                  
:: Add a empty line at line 3.            :: 
:: Call :TEXTMAN I 3 "Test.txt"           :: 
::                   ::                  
:: Add a line with a word at line 3.          :: 
:: Call :TEXTMAN I 3 "Test.txt" "Elektro [email protected]"       :: 
::                   ::  
:: Replace the line 3 with "Elektro [email protected]".        :: 
:: Call :TEXTMAN RL 3 "Test.txt" "Elektro [email protected]"       :: 
::                   :: 
:: Replace the words "Elektro" to "[email protected]" in line 3.      :: 
:: Call :TEXTMAN RS 3 "Test.txt" "Elektro" "[email protected]"      :: 
::                   :: 
:: Replace the words "Elektro" to "[email protected]" in all lines.     :: 
:: Call :TEXTMAN RSA "Test.txt" "Elektro" "[email protected]"       :: 
::                   :: 
:: Delete the first 3 characters in all lines.        :: 
:: Call :TEXTMAN C+ 3 "Test.txt"           :: 
::                   :: 
:: Delete the last 3 characters in all lines.        :: 
:: Call :TEXTMAN C- 3 "Test.txt"           :: 
::                   :: 
:: Delete the first 3 lines.            :: 
:: Call :TEXTMAN L+ 3 "Test.txt"           :: 
::                   :: 
:: Delete the last 3 lines.            :: 
:: Call :TEXTMAN L- 3 "Test.txt"           :: 
::                   :: 
:: Delete all except the line number 3.         :: 
:: Call :TEXTMAN SL 3 "Test.txt"           :: 
::                   :: 
:: Delete all except the 3 to 9 range of lines.       :: 
:: Call :TEXTMAN SR 3 9 "Test.txt"           :: 
::                   :: 
:: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: 


:TEXTMAN 
(SET /A "A=0", "LINE=0", "TOTAL_LINES=0") & (CALL :%~1 %* || (ECHO Invalid parameter & Exit /B 1)) & (GOTO:EOF) 
:AB 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "IF NOT "%%LINE%%" EQU "%~2" (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B)>> "%~3.NEW")) ELSE (if "%%B" EQU "" ((Echo %~4)>> "%~3.NEW") ELSE ((Echo %~4%%B)>> "%~3.NEW"))"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:AE 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "IF NOT "%%LINE%%" EQU "%~2" (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B)>> "%~3.NEW")) ELSE ((Echo %%B%~4)>> "%~3.NEW")"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:E 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "IF NOT "%%LINE%%" EQU "%~2" (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B) >> "%~3.NEW"))"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:I 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "IF  "%%LINE%%" EQU "%~2" (IF NOT "%~4" EQU "" ((Echo %~4) >> "%~3.NEW") ELSE (Echo+>> "%~3.NEW"))" & (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B)>> "%~3.NEW"))))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:RL 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "IF NOT "%%LINE%%" EQU "%~2" (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B)>> "%~3.NEW")) ELSE ((Echo %~4)>> "%~3.NEW")"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:RS 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "IF NOT "%%LINE%%" EQU "%~2" (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B)>> "%~3.NEW")) ELSE (CALL SET "STRING=%%B" &&  (if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((CALL ECHO %%STRING:%~4=%~5%%)>> "%~3.NEW")))"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:RSA 
(For /F "tokens=1* delims=]" %%A in ('type "%~2" ^| find /n /v ""') DO (CALL SET "STRING=%%B" && (if "%%B" EQU "" (Echo+>> "%~2.NEW") ELSE ((CALL ECHO %%STRING:%~3=%~4%%)>>"%~2.NEW")))) && (CALL :RENAMER "%~2") & (GOTO:EOF) 
:C+ 
(For /F "usebackq tokens=*" %%@ in ("%~3") DO (Call Set "LINE=%%@" && (CALL ECHO %%LINE:~%~2%% >>  "%~3.NEW"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:C- 
(For /F "usebackq tokens=*" %%@ in ("%~3") DO (Call Set "LINE=%%@" && (CALL ECHO %%LINE:~0,-%~2%% >> "%~3.NEW"))) && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:L+ 
(Call SET /A "A=%~2") && (Call TYPE "%~3" |@MORE +%%A%% > "%~3.NEW") && (CALL :RENAMER "%~3") & (GOTO:EOF) 
:L- 
(For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (CALL SET /A "TOTAL_LINES+=1")) & (CALL SET /A "TOTAL_LINES-=%~2-1") & (For /F "tokens=1* delims=]" %%A in ('type "%~3" ^| find /n /v ""') DO (Call Set /A "LINE+=1" & Call echo "%%LINE%%"|@FIND "%%TOTAL_LINES%%" >NUL) && (CALL :RENAMER "%~3" && GOTO:EOF) || (Echo %%B >> "%~3.NEW")) 
:GL 
(Call SET /A "A=%~2" && Call SET /A "A-=1") && (Call TYPE "%~3" |@MORE +%%A%% > "%temp%\getline.tmp") && (For /F "tokens=1* delims=]" %%A in ('type "%temp%\getline.tmp" ^| find /n /v ""') DO ((if "%%B" EQU "" (Echo+>> "%~3.NEW") ELSE ((Echo %%B)> "%~3.NEW"))) && ((CALL :RENAMER "%~3") & (GOTO:EOF))) 
:GR 
(For /F "tokens=1* delims=]" %%A in ('type "%~4" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "(IF "%%LINE%%" GEQ "%~2" IF "%%LINE%%" LEQ "%~3" (if "%%B" EQU "" (Echo+>> "%~4.NEW") ELSE ((Echo %%B)>> "%~4.NEW"))) && (IF "%%LINE%%" EQU "%~3" Exit /B 1)" || ((CALL :RENAMER "%~4") & (GOTO:EOF))))) 

:RENAMER 
(REN "%~1" "%~nx1.BAK") & (MOVE /Y "%~1.BAK" "%TEMP%\" >NUL) & (REN "%~1.NEW" "%~nx1") & (GOTO:EOF) 

UPDATE:

你只需要使用这部分代码从我的例行:

@Echo OFF 

Call :TEXTMAN 5 30 "TextFile.txt" 
Pause&Exit 

:TEXTMAN 
(SET /A "A=0", "LINE=0", "TOTAL_LINES=0") & (CALL :%~1 %* || (ECHO Parametro incorrecto & Exit /B 1)) & (GOTO:EOF) 
:GR 
(For /F "tokens=1* delims=]" %%A in ('type "%~4" ^| find /n /v ""') DO (Call Set /A "LINE+=1" && (CMD /C "(IF "%%LINE%%" GEQ "%~2" IF "%%LINE%%" LEQ "%~3" (if "%%B" EQU "" (Echo+>> "%~4.NEW") ELSE ((Echo %%B)>> "%~4.NEW"))) && (IF "%%LINE%%" EQU "%~3" Exit /B 1)" || ((CALL :RENAMER "%~4") & (GOTO:EOF))))) 
:RENAMER 
(REN "%~1" "%~nx1.BAK") & (MOVE /Y "%~1.BAK" "%TEMP%\" >NUL) & (REN "%~1.NEW" "%~nx1") & (GOTO:EOF) 

或者你也可以做它一步一步:

如果我们想的范围X到Y(5〜10为例)然后...

1 - 写文本文件到临时文件切割第5行:

2 - 做一个循环中TempFile开始向另一个文本文件写入从一开始的行,然后在到达“Y”行时停止。

@Echo OFF 

    Setlocal enabledelayedexpansion 

    Set /A "X=5" 
    Set /A "Y=10" 
    Set /A "Z=%Y%-%X%" 

    (Type "Test.txt" | MORE +%X%)>"TempFile.txt" 

    (For /F "Usebackq Tokens=*" %%# in ("TempFile.txt") Do (
     Set /A Line+=1 
     If not !Line! GTR %Z% (Echo %%#) Else (Exit) 
    ))>"MyRange.txt" 
+0

至少您的代码不会保留空白行 - 它将删除它们和计数的行损坏。 – foxidrive 2013-04-22 11:15:47

+0

感谢提供的想法,代码更新解析空白行:)。 – ElektroStudios 2013-04-22 13:34:57

+0

它仍然有很多错误。它在一行中删除尾随的']'它失败,'ON','OFF'或'/?',它在一行中出现''cat&dog''失败......你应该删除'Call Set/A“LINE + = 1”,因为它会降低速度(这在这里没有用)。 – jeb 2013-04-22 14:07:27

1

批次可以做到这一点,但会有性能上的损失和毒性的字符可能是一个问题 - 和文件的化妆也很重要。

下载GnuSed并运行此命令:

sed 5,30d "file.txt" >"file2.txt" 
+0

如果需要阅读大量的行和如果打印输出太多,否则只有“性能损失”,否则不。他只需要从第5行到第30行开始阅读...并且bat文件可以停止在第30行读取文件的内容。 – ElektroStudios 2013-04-22 10:51:54