gpt4 book ai didi

perl - sed/awk/perl 删除 3 行模式的前两行

转载 作者:太空宇宙 更新时间:2023-11-03 16:50:56 24 4
gpt4 key购买 nike

我有一个巨大的文本文件。我需要替换这三行的所有匹配项图案:

|pattern|some data|
|giberish|,,
|pattern|some other data|

根据模式的最后一行:

|pattern|some other data|

去掉图案的前两行,只保留最后一行

  • pattern 的第二行以两个逗号结尾,不以|pattern|开头
  • 模式行的第一行以|pattern|开始,不以两个逗号结束。
  • 模式行的第三行以|pattern|开始,不以两个逗号结束。

我试过这个:

sed 'N;N;/^|pattern|.*\n.*,,\n|pattern|.*/I,+1 d' trial.txt

运气不好

编辑:这是一个更重要的例子

#!/usr/bin/env bash
cat > trial.txt <<EOL
|pattern|sdkssd|
|.x,mz|e,dsa|,,
|pattern|sdk;sd|
|xl'x|cxm;s|,,
|pattern|aslkaa|
|l'kk|3lke|,,
|x;;lkaa|c,c,s|
|-0-ses|3dsd|
|xk;xzz|'l3ld|
|0=9c09s|klkl32|
|d0-zox|m,3,a|
|x'.za|wkl;3|
|=-0poxz|3kls|
|x-]0';a|sd;ks|
|wsd|756|
|sdw|;lksd|
|pattern|askjkas|
|xp]o]xa|lk3j2|,,
|]-p[z|lks|
EOL

它应该变成:

|pattern|aslkaa|
|l'kk|3lke|,,
|x;;lkaa|c,c,s|
|-0-ses|3dsd|
|xk;xzz|'l3ld|
|0=9c09s|klkl32|
|d0-zox|m,3,a|
|x'.za|wkl;3|
|=-0poxz|3kls|
|x-]0';a|sd;ks|
|wsd|756|
|sdw|;lksd|
|pattern|askjkas|
|xp]o]xa|lk3j2|,,
|]-p[z|lks|

@zdim:

文件的前三行:

|pattern|sdkssd|
|.x,mz|e,dsa|,,
|pattern|sdk;sd|

满足模式。所以他们被替换为

|pattern|sdk;sd|

所以文件的顶部现在变成:

|pattern|sdk;sd|
|xl'x|cxm;s|,,
|pattern|aslkaa|
|l'kk|3lke|,,
...

前三行是:

|pattern|sdk;sd|
|xl'x|cxm;s|,,
|pattern|aslkaa|

满足模式,所以它们被替换为:

|pattern|aslkaa|

所以现在文件的顶部是:

|pattern|aslkaa|
|l'kk|3lke|,,
|x;;lkaa|c,c,s|
|-0-ses|3dsd|
....

@JosephQuinsey:

考虑这个文件:

#!/usr/bin/env bash
cat > trial.txt <<EOL
|pattern|blabla|
|||4|||-0.97|0|1429037262.8271||20160229||1025||1000.0|0.01|,,
|pattern|blable|
|||5|||-1.27|0|1429037262.854||20160229||1025||1000.0|0.01|,,
|pattern|blasbla|
|||493|||-0.22|5|1429037262.8676||20170228||1025||1000.0|0.01|,,
|||11|||-0.22|5|1429037262.8676||20170228||1025||1000.0|0.01|,|T|347||1429043438.1962|-0.22|5|0||-0.22|1429043438.1962|,|Q|346||1429043437.713|-0.24|26|-0.22|5|||1429043437.713|
|pattern|jksds|
|||232|||-5.66|0|1429037262.817||20150415||1025||1000.0|0.01|,,
|pattern|bdjkds|
|||123q|||-7.15|0|1429037262.8271||20150415||1025||1000.0|0.01|,,
|pattern|blabla|
|||239ps|||-1.38|79086|1429037262.8773||20150415||1025||1000.0|0.01|,,
|||-92opa|||-1.38|79086|1429037262.8773||20150415||1025||1000.0|0.01|,|T|1||1428969600.5019|-0.99|1|11||||,
|||kj2w|||-1.38|79086|1429037262.8773||20150415||1025||1000.0|0.01|,|T|2||1428969600.5019|-1|1|11||||,
|||0293|||-1.38|79086|1429037262.8773||20150415||1025||1000.0|0.01|,|T|3||1428969600.5019|-1.01|1|11||||,
|||2;;w32|||-1.38|79086|1429037262.8773||20150415||1025||1000.0|0.01|,|T|4||1428969600.5019|-1.11|1|11||||,
EOL

最佳答案

这是一个简单的例子,使用缓冲区来收集和管理模式线

use warnings;
use strict;
use feature 'say';

my $file = shift or die "Usage: $0 file\n";

open my $fh, '<', $file or die "Can't open $file: $!";

my @buf;

while (<$fh>) {
chomp;
if (/^\|pattern\|/ and not /,,$/) {
@buf = $_; # start the buffer (first line) or overwrite (third)
}
elsif (/,,$/ and not /^\|pattern\|/) {
if (@buf) { push @buf, $_ } # add to buffer with first line in it
else { say } # not part of 3-line-pattern; print
}
else {
say for @buf; # time to print out buffer
@buf = (); # ... empty it ...
say # and print the current line
}
}

这会打印预期的输出。

解释。

  • 模式行进入缓冲区,当我们得到“第三行”时,需要删除前两行。然后每当我们看到 ^|pattern| 时“分配”给数组-- 如果是第一行则启动缓冲区,如果是第三行则重新初始化数组(删除其中的内容)

  • ,, 结尾的行被添加到缓冲区,如果那里已经有一行。没有什么禁止以 ,, 结尾的行就是这样——它们可能不在模式之内;在那种情况下只需打印它

  • 所以每个|pattern| line 直接设置缓冲区——启动它或重置它。因此,一旦我们遇到既没有 ^|pattern| 的行也不,,$我们可以打印出我们的缓冲区,以及那一行

请更全面地测试,我还没有做到的。


为了在管道或文件中运行它,请使用 "magical" <> 文件句柄。于是就变成了

use warnings;
use strict;
use feature 'say';

my @buf;

while (<>) { # reads lines from files given on command line, or from STDIN
...
}

现在您可以将其运行为 data | script.plscript.pl datafile . (为此使脚本可执行,或用作 perl script.pl 。)

脚本的输出转到 STDOUT它可以通过管道传输到其他程序或重定向到文件。

关于perl - sed/awk/perl 删除 3 行模式的前两行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58087298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com