我有一个巨大的文本文件。我需要替换所有出现的这三行 模式:
|pattern|some data|
|giberish|,,
|pattern|some other data|
在模式的最后一行:
|pattern|some other data|
删除模式的前两行,仅保留最后一行。
|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
答案 0 :(得分:5)
这很简单,使用缓冲区来收集和管理图案线
MyList
这将打印预期的输出。
说明。
模式行放在缓冲区中,当我们获得“第三行”时,需要删除前两个行。然后,每当我们看到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|
也没有^|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.pl
的身份运行它。 (为此使脚本可执行,或用作script.pl datafile
。)
脚本的输出将转到perl script.pl
,该脚本可以通过管道传输到其他程序或重定向到文件。
答案 1 :(得分:1)
更新后的答案: :以下 sed 解决方案应该可以工作:
sed '/\n/!N;/\n.*\n/!N;/^|pattern|.*\n.*,,\n|pattern|/!{P;D;};s/[^\n]*\n//;D;'
说明:
/\n/!N
如果P空间只有一行,请阅读下一行/\n.*\n/!N
,如果P空间只有两行,请读第三行/^|pattern|.*\n.*,,\n|pattern|/
测试第一行和第三行是否以| pattern |开头,中间行以两个逗号结尾!{P;D;}
如果匹配失败 ,则打印第一行并重新开始s/[^\n]*\n//;D;
否则,如果匹配成功 ,请删除前两行,然后重新开始。答案 2 :(得分:1)
这可能取决于文件的大小,但如果文件大小小于允许的内存大小,怎么办:
|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|
输出:
string tableName = _awsSettings.TableSettings.Table + _awsSettings.TableSettings.Suffix;
Table table = Table.LoadTable(_amazonDynamoDb, tableName);
DocumentBatchGet batch = table.CreateBatchGet();
await batch.ExecuteAsync();
List<Document> results = batch.Results;
return results.As<Lab>();
答案 3 :(得分:1)
awk解决方案:
awk -v pa=pattern '
$0 ~ pa {
do {
hold=$0;
getline;
hold=hold "\n" $0;
getline;
} while(match($0, pa));
print hold
}
1' trial.txt
想法是缓冲与模式匹配的行,然后缓冲之后的行。如果下一行也与模式匹配,则循环,这一次将缓冲最近的匹配行及其后一行。这样具有删除需要替换的行的作用。
当循环停止时,缓冲区包含的第一行要么是替换已删除行的行,要么就是不被删除的第一模式匹配。无论哪种方式,缓冲区的内容都会被打印出来。
需要最后的1
语句来打印结束while循环的行以及所有其他与模式匹配后的第一或第二行的行。
答案 4 :(得分:1)
这可能对您有用(GNU sed):
sed ':a;N;s/[^\n]*/&/3;Ta;/^|pattern|.*\n.*,,\n|pattern|/{/,,\n.*\n\|,,$/!{s/.*\n//;ba}};P;D' file
用文件的后三行填充模式空间。如果第一模式与当前三行匹配,而第一行或第三行均未以,,
结尾,则删除前两行并重复。否则,打印并删除三行窗口的第一行并重复。