简体   繁体   English

如何从文本文件中的第一个空行开始删除所有行?

[英]How to remove all lines from a text file starting at first empty line?

What is the best way to remove all lines from a text file starting at first empty line in Bash?从 Bash 中的第一个空行开始从文本文件中删除所有行的最佳方法是什么? External tools (awk, sed...) can be used!可以使用外部工具(awk、sed...)!

Example例子

1: ABC
2: DEF
3:
4: GHI

Line 3 and 4 should be removed and the remaining content should be saved in a new file.应删除第 3 行和第 4 行,并将剩余内容保存在新文件中。

使用GNU sed

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

With AWK :使用AWK

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

Contents of output.txt output.txt 的内容

$ cat output.txt 
ABC
DEF

Walkthrough: For lines that matches ^$ (start-of-line, end-of-line), exit (the whole script).演练:对于匹配 ^$(行首、行尾)的行,退出(整个脚本)。 For all lines, print the whole line -- of course, we won't get to this part after a line has made us exit.对于所有行,打印整行——当然,在一行让我们退出后,我们不会到达这一部分。

Bet there are some more clever ways to do this, but here's one using bash's 'read' builtin.打赌有一些更聪明的方法可以做到这一点,但这里有一个使用 bash 的“读取”内置函数。 The question asks us to keep lines before the blank in one file and send lines after the blank to another file.这个问题要求我们在一个文件中保留空白之前的行,并将空白之后的行发送到另一个文件。 You could send some of standard out one place and some another if you are willing to use 'exec' and reroute stdout mid-script, but I'm going to take a simpler approach and use a command line argument to let me know where the post-blank data should go:如果您愿意使用'exec'并重新路由stdout mid-script,您可以将一些标准发送到一个地方,然后再发送一些,但我将采用一种更简单的方法并使用命令行参数让我知道在哪里后空白数据应该去:

#!/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

run it like this:像这样运行它:

$ ./delete_from_empty.sh rest_of_stuff < demo

output is:输出是:

ABC
DEF

and 'rest_of_stuff' has和 'rest_of_stuff' 有

GHI

if you want the before-blank lines to go somewhere else besides stdout, simply redirect:如果您希望前空白行除 stdout 之外的其他地方,只需重定向:

$ ./delete_from_empty.sh after_blank < input_file > before_blank

and you'll end up with two new files: after_blank and before_blank.你最终会得到两个新文件:after_blank 和 before_blank。

Perl version Perl 版本

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

This creates two output files and iterates over the demo data.这将创建两个输出文件并迭代演示数据。 When it hits a blank line, it flips the output from one file to the other.当它遇到一个空行时,它会将输出从一个文件翻转到另一个文件。

Creates创造

stuff:东西:

ABC
DEF

rest_of_stuff: rest_of_stuff:

<blank line>
GHI

Another awk would be:另一个 awk 是:

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

By setting the record separator RS to be an empty string, we define the records as paragraphs separated by a sequence of empty lines.通过将记录分隔符RS设置为空字符串,我们将记录定义为由一系列空行分隔的段落 It is now easily to adapt this to select the nth block as:现在很容易调整它以选择第 n 个块:

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

There is a problem with this method when processing files with a DOS line-ending (CRLF).在处理带有 DOS 行尾 (CRLF) 的文件时,此方法存在问题。 There will be no empty lines as there will always be a CR in the line.不会有空行,因为行中总会有一个 CR。 But this problem applies to all presented methods.但是这个问题适用于所有提出的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM