【问题标题】:How to remove all lines from a text file starting at first empty line?如何从第一个空行开始的文本文件中删除所有行?
【发布时间】:2015-11-22 02:37:44
【问题描述】:

从 Bash 中的第一个空行开始从文本文件中删除所有行的最佳方法是什么?可以使用外部工具(awk、sed...)!

例子

1: ABC
2: DEF
3:
4: GHI

应删除第 3 行和第 4 行,并将剩余内容保存在新文件中。

【问题讨论】:

    标签: linux bash awk sed


    【解决方案1】:

    GNU sed:

    sed '/^$/Q' "input_file.txt" > "output_file.txt" 
    

    【讨论】:

      【解决方案2】:

      另一个 awk 是:

      awk -vRS= '1;{exit}' file
      

      通过将记录分隔符RS 设置为空字符串,我们将记录定义为由一系列空行分隔的段落。现在很容易调整它以选择第 n 个块:

      awk -vRS= '(FNR==n){print;exit}' file
      

      在处理带有 DOS 行尾 (CRLF) 的文件时,此方法存在问题。不会有空行,因为行中总是有一个 CR。但这个问题适用于所有提出的方法。

      【讨论】:

        【解决方案3】:

        AWK:

        $ awk '/^$/{exit} 1' test.txt > output.txt
        

        output.txt的内容

        $ cat output.txt 
        ABC
        DEF
        

        演练:对于匹配 ^$(行首、行尾)的行,退出(整个脚本)。对于所有行,打印整行——当然,在一行让我们退出后,我们不会进入这部分。

        【讨论】:

          【解决方案4】:

          Perl 版本

           perl -e '
                  open $fh, ">","stuff";  
                  open $efh, ">", "rest_of_stuff"; 
                  while(<>){
                     if ($_ !~ /\w+/){
                           $fh=$efh;
                     } 
                     print $fh $_;
                   }
                      ' demo
          

          这会创建两个输出文件并遍历演示数据。当它遇到一个空行时,它会将输出从一个文件翻转到另一个文件。

          创造

          东西:

          ABC
          DEF
          

          rest_of_stuff:

          <blank line>
          GHI
          

          【讨论】:

            【解决方案5】:

            打赌有一些更聪明的方法可以做到这一点,但这里有一个使用 bash 的 'read' 内置函数的方法。该问题要求我们将空白前的行保留在一个文件中,并将空白后的行发送到另一个文件。如果您愿意使用 'exec' 并重新路由 stdout 中间脚本,您可以将一些标准发送到一个地方和另一个地方,但我将采用更简单的方法并使用命令行参数让我知道在哪里后空白数据应该去:

            #!/bin/bash
            
            # script takes as argument the name of the file to send data once a blank line
            # found
            found_blank=0
            while read stuff; do
                if [ -z $stuff ] ; then
                        found_blank=1
                fi
                if [ $found_blank ] ; then
                        echo $stuff > $1
                else
                        echo $stuff
                fi
            done
            

            像这样运行它:

            $ ./delete_from_empty.sh rest_of_stuff < demo
            

            输出是:

            ABC
            DEF
            

            而“rest_of_stuff”有

            GHI
            

            如果您希望之前的空白行转到 stdout 之外的其他位置,只需重定向:

            $ ./delete_from_empty.sh after_blank < input_file > before_blank
            

            您最终会得到两个新文件:after_blank 和 before_blank。

            【讨论】:

            • 一些cmets:在当前状态下,你会忽略反斜杠字符。使用read -r 来防止这种情况(请参阅man read)。其次,您可以摆脱$found_blank 测试,只需直接进行第一次检查:if [ -z "$stuff" ]; then echo "$stuff" &gt; "$1"; else echo "$stuff"; fi。此外,引用您的 $stuff 也很重要,否则可能会忽略仅包含空格的行。您可以摆脱stuff 并使用REPLY 代替,它是代表read 答案的bash 内置函数
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-20
            • 1970-01-01
            • 1970-01-01
            • 2014-12-03
            相关资源
            最近更新 更多