文本操作和删除

时间:2009-11-20 01:11:49

标签: linux bash sed

我有一个由我的工具生成的文本文件,其结构如下所示。

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上做到这一点?任何建议都会有所帮助。

5 个答案:

答案 0 :(得分:1)

perl -00 -ne 'print if $.%2==0' 

-00标志将记录分隔符设置为空行。

答案 1 :(得分:0)

我会awk超过sed。构建一个列表,直到您点击/-+$/,然后输出您存储的多行部分,直到每个虚线为止。

编辑:在此之前我会去perl,但是awk也很有趣。

答案 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;
}