脚本删除文本文件中的一定数量的行?

时间:2015-02-05 00:26:55

标签: bash shell batch-file cmd

我是社区的新手,所以请耐心等待。我有一个超过200万行的文本文件。该文件有一个标题,50行实际数据,然后10行显示相同的标题,页码,日期和其他信息,我不需要从我用来生成文件的应用程序。然后一遍又一遍。

是否可以使用脚本每50行删除10行?

2 个答案:

答案 0 :(得分:1)

您可以使用使用几个第三方.exe程序的批处理文件来执行此操作。技巧包括将文件重定向到子例程的Stdin和Stdout,因此可以在子例程中以适当的方式移动标准句柄的文件指针来执行文件的处理。您可以在this post查看类似方法的示例。

@echo off
setlocal EnableDelayedExpansion

if "%~1" equ ":ProcessFile" goto %1

set /A keep=50, delete=10

rem Invoke a subroutine to process the file via redirected Stdin and Stdout
rem use CMD /C so the loop inside it can be broken with EXIT /B

cmd /C call "%~F0" :ProcessFile < theFile.txt >> theFile.txt
goto :EOF


:ProcessFile

rem Initialize the process: preserve first N lines in Stdin
for /L %%i in (1,1,%keep%) do set /P "line="
rem ...and move Stdout file pointer to the same place
FilePointer 0 0 /C
FilePointer 1 %errorlevel%

rem Process the rest of lines in an endless loop
for /L %%_ in ( ) do (

   rem Read M lines without copy they (delete they)
   rem (advance just Stdin file pointer)
   for /L %%i in (1,1,%delete%) do set /P "line="

   rem ...and read and copy the next N lines
   rem (both Stdin and Stdout advance the same amount)
   for /L %%i in (1,1,%keep%) do set /P "line=!line!"

   rem Check for the EOF in Stdin after the last block copied
   set "line="
   set /P "line="
   if not defined line (
      rem EOF detected: truncate the Stdout file after the last written line
      TruncateFile 1
      rem ...and terminate
      exit /B
   )

)

此方法的一个有趣方面是,处理是在相同的文件中实现的,也就是说,该过程不需要额外的空间来存储输出文件。数据部分从同一文件中的一个位置移动到另一个位置,最后截断剩余的空间。当然,这个方法销毁原始文件,所以你应该在使用这个程序之前复制它。

此代码很可能在复制或删除的每个部分中都有一行无效的错误,但运行测试并相应地调整值要简单得多。我建议你创建一个包含4或5个部分的文件,并将其用于测试。此外,检测文件结尾的方法可能需要一些调整。如果您发布测试结果,我可以帮助您修复这些细节。

您可以阅读此内容的进一步说明,并在this site下载FilePointer.exe和TruncateFile.exe辅助程序。

答案 1 :(得分:0)

这是一个awk脚本,它向ed发送命令,删除H个行,每行标题段之间保留T行数{1}}:

awk -v sz="`cat file.txt | wc -l`" -v H=10 -v T=40 'BEGIN { 
  print "w"
  idx=1
  while(idx<sz) {
    print idx "," idx+H-1 "d"
    idx+=(H+T)
  }
}' | cat -n | sort -rn | cut -f2- | ed file.txt

这里,H是要删除的标题行数,T是下一个标题部分之前的剩余行数。

cat -n | sort -rn | cut -f2-管道是一种扭转awk产生的输出顺序的技巧(最后一行是第一行,第二行是第二行,等等。)