【问题标题】:Extract N lines from file using single windows command使用单个 windows 命令从文件中提取 N 行
【发布时间】:2015-01-13 22:32:30
【问题描述】:

有没有办法从一个文件中提取/复制前 X 行,然后使用 windows 命令提示符通过单个命令将它们输入到另一个文件中?

我可以使用以下方法删除前 X 行:
more +X [文件_包含数据] > [file_to_export_data_to]

如果 head 命令有效,我想我可以这样做:
head -X [文件包含数据] > [file_to_export_data_to]

但不幸的是,这不起作用。

如果 Windows 有一个“less”命令但又没有运气,那就太好了。

当谈到这些东西时,我是一个完全的新手,所以我确定我错过了一些明显的东西。我不想安装任何东西或使用命令提示符以外的东西。

谢谢

【问题讨论】:

  • PowerShell:get-content file | select-object -first 10。 (PowerShell 是从 Windows 7 开始内置的。)
  • POWERSHELL> 获取内容 int.txt | select-object -first 10 > out.txt

标签: windows cmd command-prompt


【解决方案1】:

最简单的单命令解决方案是使用 Powershell Get-Content。

N - 行数。

从文件开始:

Get-Content -Head N file.txt

从文件末尾开始:

Get-Content -Tail N file.txt

【讨论】:

  • 我得到“找不到与参数名称'Head'匹配的参数。”错误。
  • 检查 PowerShell 的版本,我认为它是旧的。或者命令中某处的拼写错误。
  • 您可能必须使用“TotalCount”而不是“Head”。见docs.microsoft.com/en-us/powershell/module/…
  • 在命令末尾添加` > tgetfile.txt`,以管道传输到文件而不是仅仅显示。
【解决方案2】:

您可以从 cmd.exe 控制台使用 PowerShell:

 powershell -command "& {get-content input.txt|select-object -first 10}" >output.txt

您可以创建一个 DOSKEY 宏以使其更易于从命令行使用:

doskey head=powershell -command "& {get-content $1|select-object -first $2}"

用法:

head input.txt 10 >output.txt

但您不能在批处理脚本中使用 DOSKEY 宏。

您可以创建一个 head.bat 脚本并将其放置在 PATH 中包含的文件夹中:

head.bat

@powershell -command "& {get-content %1|select-object -first %2}"

在命令行中,您可以使用head input.txt 10 >output.txt

在批处理脚本中,您可以使用 call head input.txt 10 >output.txt

我选择不将输出文件作为参数,以防您只想将结果显示在屏幕上而不是写入文件。

【讨论】:

    【解决方案3】:

    为了获得正确的 utf8 输出,请在 powershell 中执行以下操作

    chcp 65001
    
    $OutputEncoding = New-Object -typename System.Text.UTF8Encoding
    
    get-content input.txt -encoding UTF8 |select-object -first 10000 > output.txt
    

    这会将 input.txt(utf8 格式的文件)的前 10000 行以正确的编码转换为 output.txt。

    【讨论】:

      【解决方案4】:
      (@FOR /f "tokens=1* delims=:" %a IN ('findstr /n "^" "standardwaffle.txt"') DO @IF %a leq 7 ECHO(%b)>u:\junk.txt
      

      会将standardwaffle.txt 的前 7 行提取到u:\junk.txt,所以它在一个 cmd 行中 - 但我会拒绝你可靠地输入。

      它还会删除源代码行上的任何前导 :

      @ECHO OFF
      SETLOCAL
      IF %1 lss 0 (SET /a line=-%1) ELSE (SET /a line=%1)
      FOR /f "tokens=1* delims=:" %%a IN ('findstr /n "^" "%~2"') DO IF %%a leq %line% ECHO(%%b
      
      GOTO :EOF
      

      这批,保存为head.bat 放置在您路径上的任何位置将允许您使用

      head -n standardwaffle.txt >junk.txt
      

      standardwaffle.txt的第一行n提取到junk.txt

      - 是可选的

      但是这涉及在您的机器上安装批处理。您的“不安装”要求是否禁止这样做,还是“安装”仅适用于 3rd 方实用程序?

      【讨论】:

      • 批处理文件似乎首先读取整个文件,因为在 500Mb 的文件中它需要很多,而在小文件中它可以立即运行。另一方面,dbenham 的 Powershell 解决方案似乎可以快速输出预期的部分,因此它可以在仍在读取文件的其余部分时被中断。
      • 我也希望有一个批处理/cmd 解决方案,但我有一个 25GiB 的文件可以使用。绝对不希望它试图将其读入内存。 ://
      【解决方案5】:
      Set Inp = WScript.Stdin
      Set Outp = Wscript.Stdout
      x = 0
          Do Until Inp.AtEndOfStream
                    x = x + 1
              OutP.WriteLine Inp.Readline
                    If x = 5 then Exit Do
          Loop
      

      这会打印第 1 到 5 行。要使用

      cscript //nologo <path to script.vbs> <inputfile >outputfile
      

      【讨论】:

        【解决方案6】:

        你可以用这个:

        break>"%temp%\empty"&&fc "%temp%\empty" "%file_to_process%" /lb  X /t |more +4 | findstr /B /E /V "*****"
        

        您应该将 X 替换为所需的行。或者将此命名为 head.bat

        break>"%temp%\empty"&&fc "%temp%\empty" "%file_to_process%" /lb  %~1 /t |more +4 | findstr /B /E /V "*****"
        

        【讨论】:

          【解决方案7】:

          如果您想坚持使用简单的 Windows 命令,您可以使用它,但对于大文件会有点慢 ;-)(我在下面添加了第二个解决方案,效果更好 :-) 这会提取最后 100 条记录任何长度的文件)

          find /n " " <test.txt >test.tmp
          for /l %%i in (1,1,100) do find "[%%i]" <test.tmp >test.tmp2
          for /f "delims=] tokens=2" %%i in (test.tmp2) do echo %%i >>test.new
          del test.tmp
          del test.tmp2
          move /y test.new test.txt
          
          find /v /n "" <test.txt >test.tmp
          for /f "delims=: tokens=2 %%i in ('find /v /c "" test.txt') do set /a NR=%%i
          set /a NS=%NR%-100
          for /l %%i in (%NS%, 1, %NR%) do find "[%%i]" <test.tmp >>test.tmp2
          for /f %%i "delims=] tokens=2 %%i in (test.tmp2) do echo %%i >>test.new
          move /y test.new test.txt
          

          【讨论】:

          • 你是对的 - 这很慢:)。第二行不应该是&gt;&gt;吗?您还应该提到在哪里插入“Startline”和“Endline”(对我来说这很明显,但没有一些经验,很难说)
          • 是的,你是对的,对不起我的错(错字),是的,我认为很明显 1 和 100 是开始和结束行,你可以改变它们以提取文件的任何部分你想要的基于行号。
          • 介意扩大您的答案以使其成为一个好的答案吗? (它是cmd,而不是DOS。您的代码不会在DOS 中运行)
          【解决方案8】:

          无需读取整个文件;只需从文件开头提取所需的行(头):

          set file=<file>
          set line=<required first few lines>
          type nul > tmp & fc tmp "%file%" /lb %line% /t | find /v "*****" | more +2
          

          从file.txt中提取前9行并写入nine.txt的单行示例

          for /f "tokens=* delims=[" %i in ('type "file.txt" ^| find /v /n "" ^| findstr /b /r \[[1-9]\]') do set a=%i& set a=!a:*]=]!& echo:!a:~1!>> nine.txt
          

          保留空白行、以分号开头的行、前导空格并保留分隔符和空格。

          在 Win 10 x64 CMD 上测试

          【讨论】:

            猜你喜欢
            • 2013-05-11
            • 2012-01-17
            • 2015-02-28
            • 2014-12-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-10-24
            • 1970-01-01
            相关资源
            最近更新 更多