【发布时间】:2015-11-22 02:37:44
【问题描述】:
从 Bash 中的第一个空行开始从文本文件中删除所有行的最佳方法是什么?可以使用外部工具(awk、sed...)!
例子
1: ABC
2: DEF
3:
4: GHI
应删除第 3 行和第 4 行,并将剩余内容保存在新文件中。
【问题讨论】:
从 Bash 中的第一个空行开始从文本文件中删除所有行的最佳方法是什么?可以使用外部工具(awk、sed...)!
例子
1: ABC
2: DEF
3:
4: GHI
应删除第 3 行和第 4 行,并将剩余内容保存在新文件中。
【问题讨论】:
与GNU sed:
sed '/^$/Q' "input_file.txt" > "output_file.txt"
【讨论】:
另一个 awk 是:
awk -vRS= '1;{exit}' file
通过将记录分隔符RS 设置为空字符串,我们将记录定义为由一系列空行分隔的段落。现在很容易调整它以选择第 n 个块:
awk -vRS= '(FNR==n){print;exit}' file
在处理带有 DOS 行尾 (CRLF) 的文件时,此方法存在问题。不会有空行,因为行中总是有一个 CR。但这个问题适用于所有提出的方法。
【讨论】:
与AWK:
$ awk '/^$/{exit} 1' test.txt > output.txt
output.txt的内容
$ cat output.txt
ABC
DEF
演练:对于匹配 ^$(行首、行尾)的行,退出(整个脚本)。对于所有行,打印整行——当然,在一行让我们退出后,我们不会进入这部分。
【讨论】:
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
【讨论】:
打赌有一些更聪明的方法可以做到这一点,但这里有一个使用 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。
【讨论】:
read -r 来防止这种情况(请参阅man read)。其次,您可以摆脱$found_blank 测试,只需直接进行第一次检查:if [ -z "$stuff" ]; then echo "$stuff" > "$1"; else echo "$stuff"; fi。此外,引用您的 $stuff 也很重要,否则可能会忽略仅包含空格的行。您可以摆脱stuff 并使用REPLY 代替,它是代表read 答案的bash 内置函数