【问题标题】:Script to remove a set number of lines in a text file? [closed]删除文本文件中设定的行数的脚本? [关闭]
【发布时间】:2015-02-05 00:26:55
【问题描述】:

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

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

【问题讨论】:

  • 您能否提供有关您要排除的行的信息?示例内容会有所帮助。
  • 同意。了解您要排除的行的独特之处,某种可用于切换想要与不需要的序列的顺序将非常有帮助。
  • 如果您只是想跳过 60 行中的前 10 行,使用 awk 命令将很有用。 awk '{ if (NR % 60 > 10) { print $_ } } '
  • @vijayalakshmi d,您提供的 awk 命令不符合 OP 的要求。

标签: bash shell batch-file cmd


【解决方案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
   )

)

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

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

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

【讨论】:

    【解决方案2】:

    这是一个awk 脚本,它向ed 发送命令,删除H 的行数,T 保留在每个标题部分之间的行数:

    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 产生的输出的顺序(最后一行是第一行,倒数第二行是第二行,等等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多