这个问题有一个很好的答案,您可以使用awk '!seen[$0]++' file.txt从文件中删除不连续的重复行。只有当文件与模式匹配时,才能从文件中删除不连续的重复行?例如,只有当它们包含字符串"#####“时
示例输入
deleteme.txt ##########
1219: 'PCM BE PTP'
deleteme.txt ##########
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1222: , 'PCM BE PTP UT'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1223: , 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1225: , 'PCM FE/MID PTP'期望输出
deleteme.txt ##########
1219: 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1222: , 'PCM BE PTP UT'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
1223: , 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
1225: , 'PCM FE/MID PTP'发布于 2019-03-03 19:22:19
你可以用
awk '!/#####/ || !seen[$0]++'或者,作为埃德·莫顿,同义词
awk '!(/#####/ && seen[$0]++)'在这里,!seen[$0]++和往常一样做同样的事情,它将删除任何重复行。!/#####/部件匹配包含#####模式并否定匹配的行。这两种模式与||相结合,将删除在它们中包含#####模式的所有重复行。
见演示
s="deleteme.txt ##########
1219: 'PCM BE PTP'
deleteme.txt ##########
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1222: , 'PCM BE PTP UT'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1223 #####: , 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1225: , 'PCM FE/MID PTP'"
awk '!/#####/ || !seen[$0]++' <<< "$s"输出:
deleteme.txt ##########
1219: 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1222: , 'PCM BE PTP UT'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
1223 #####: , 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
1225: , 'PCM FE/MID PTP'发布于 2019-03-04 14:41:53
使用文件slurp模式尝试这个Perl命令行regex解决方案。
perl -0777 -ne ' $z=$y=$_;
while( $y ne $x)
{ $z=~s/(^[^\n]+?\s+##########.*?$)(.+?)\K(\1\n)//gmse ; $x=$y ;$y=$z } ;
print "$z" '用给定的输入
$ cat toucan.txt
deleteme.txt ##########
1219: 'PCM BE PTP'
deleteme.txt ##########
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1222: , 'PCM BE PTP UT'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1223: , 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1225: , 'PCM FE/MID PTP'
$ perl -0777 -ne ' $z=$y=$_; while( $y ne $x) { $z=~s/(^[^\n]+?\s+##########.*?$)(.+?)\K(\1\n)//gmse ; $x=$y ;$y=$z } ; print "$z" ' toucan.txt
deleteme.txt ##########
1219: 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
deleteme2.txt ##########
1222: , 'PCM BE PTP UT'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
1223: , 'PCM BE PTP'
1221: , 'PCM FE/MID PTP UT','PCM IA 1 PTP'
1225: , 'PCM FE/MID PTP'
$发布于 2019-03-03 19:54:50
每当我想到匹配模式和选择性打印时,我都会想到实用的提取和报告语言: Perl!这里有一个Perl一行程序,它能满足您的要求。您应该能够将其复制粘贴到shell中,并使其工作:
perl -wnle 'BEGIN { $rows_with_five_hashes = {}; } $thisrow = $_; if ($thisrow =~ /[#]{5}/) { if (!exists $rows_with_five_hashes->{$thisrow}) { print; } $rows_with_five_hashes->{$thisrow}++; } else { print; }' input.txt下面是相同的Perl,为了清晰起见,使用了换行符和注释(注意:这是不可执行的):
BEGIN {
# create a counter for rows that match the pattern
$rows_with_five_hashes = {};
}
# capture the row from the input file
$thisrow = $_;
if ($thisrow =~ /[#]{5}/) {
if (!exists $rows_with_five_hashes->{$thisrow}) {
# this row matches the pattern and we haven't seen it before
print;
}
# Increment the counter for rows that match the pattern.
# Do this AFTER we print, or else our "exists" print logic fails.
$rows_with_five_hashes->{$thisrow}++;
}
else {
# print all rows that don't match the pattern
print;
}Ruby具有类似的“一行”功能,可以直接在命令行上运行代码(大部分代码是从Perl借来的)。
有关wnle命令行开关的更多信息,请查看Perl文档中有关这一点。如果您有许多想要修改的文件,并使用单个Perl命令保留原始文件的备份副本,请检查这些文档中的-i开关。
如果您发现自己一直在运行这个脚本,并且希望保留一个方便的可执行脚本,那么您可以很容易地调整这个脚本,以便在任何有Perl解释器的系统上运行。
https://stackoverflow.com/questions/54972535
复制相似问题