我有一个由我的工具生成的文本文件,其结构如下所示。
1 line text
(space)
multiple
lines
text
(space)
multiple
lines
text
nr 2
---------------------------------------------------------- (58 '-' characters)
different 1 line text
(space)
different
multiple
lines
text
(space)
different
multiple
lines
text
nr 2
----------------------------------------------------------
different 1 line text
(space)
different
multiple
lines
text
(space)
different
multiple
lines
text
nr 2
----------------------------------------------------------
(space)
每个文件以1行文本开头,以“ - ”结尾标记分隔符和空格。每个文件中有不同数量的部分,每个“中间”的部分以“ - ”符号开头和结尾。以下是我想要实现的目标。
multiple
lines
text
(space)
different
multiple
lines
text
(space)
different
multiple
lines
text
我想删除所有一个衬垫,所有58' - '字符分隔线和所有'第二'多个衬垫,并且每个部分只有'第一'个多个衬垫,一个在另一个下面用空格划分。有人可以推荐如何在Linux上做到这一点?任何建议都会有所帮助。
答案 0 :(得分:1)
perl -00 -ne 'print if $.%2==0'
-00
标志将记录分隔符设置为空行。
答案 1 :(得分:0)
我会awk
超过sed
。构建一个列表,直到您点击/-+$/
,然后输出您存储的多行部分,直到每个虚线为止。
答案 2 :(得分:0)
以下perl
脚本将执行您想要的操作(我发现sed
不适合跨越多行的任务。)
#!/usr/bin/perl
$first = 1;
$skip = 2;
while (<>) {
chomp;
$ln = $_;
if ($ln =~ /^-{58}$/) {
$skip = 2;
next;
}
if ($skip > 0) {
$skip--;
if ($skip == 0) {
if ($first) {
$first = 0;
} else {
print "\n";
}
}
next;
}
if ($skip == 0) {
print $ln . "\n";
if ($ln =~ /^$/) {
$skip = -1;
}
}
}
这是基于您的(space)
行只是空行的假设。如果不是,则需要调整底部附近的/^$/
模式以匹配实际情况。
它基本上是由$skip
变量控制的简化状态机。如果这是肯定的,那么您将跳过那么多行(从2开始,每---
行设置为2)。
当$skip
达到零时,它会一直停留在那里,直到你得到一个空行(你正在回忆这些行)。获得空行时,将其设置为-1并停止回显行。
$first
变量有点黑客,以确保输出中没有尾随空行。
这是我从输入文件中获得的输出:
multiple
lines
text
(space)
different
multiple
lines
text
(space)
different
multiple
lines
text
我相信你所追求的是什么。
答案 3 :(得分:0)
修改:打印第一个多行组:
awk 'BEGIN {toggle=1} /^\(space)$/ {if (!toggle) print ""; toggle=!toggle; next} {if (! toggle) print}' file.txt
原始:打印第二个多行组:
awk '/^\(space)$/ { accum=""; next} /^-+$/ {print accum; accum=""; next} {accum=accum"\n"$0}' file.txt
答案 4 :(得分:-1)
gawk的
awk '{ print $2 }' RS="-\n" FS="\n\n" file
输出
$ ./shell.sh
multiple
lines
text
different
multiple
lines
text
different
multiple
lines
text
Perl中的等价物。
$\ = "\n";
$/ = "-\n";
while (<>) {
chomp;
($f1,$f2) = split "\n\n", $_ ;
print $f2;
}