首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只有当重复行与模式匹配时,才删除它们

只有当重复行与模式匹配时,才删除它们
EN

Stack Overflow用户
提问于 2019-03-03 18:59:24
回答 4查看 1.6K关注 0票数 5

这个问题有一个很好的答案,您可以使用awk '!seen[$0]++' file.txt从文件中删除不连续的重复行。只有当文件与模式匹配时,才能从文件中删除不连续的重复行?例如,只有当它们包含字符串"#####“时

示例输入

代码语言:javascript
复制
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'

期望输出

代码语言:javascript
复制
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'
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-03-03 19:22:19

你可以用

代码语言:javascript
复制
awk '!/#####/ || !seen[$0]++'

或者,作为埃德·莫顿,同义词

代码语言:javascript
复制
awk '!(/#####/ && seen[$0]++)'

在这里,!seen[$0]++和往常一样做同样的事情,它将删除任何重复行。!/#####/部件匹配包含#####模式并否定匹配的行。这两种模式与||相结合,将删除在它们中包含#####模式的所有重复行。

演示

代码语言:javascript
复制
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"

输出:

代码语言:javascript
复制
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'
票数 8
EN

Stack Overflow用户

发布于 2019-03-04 14:41:53

使用文件slurp模式尝试这个Perl命令行regex解决方案。

代码语言:javascript
复制
perl -0777 -ne ' $z=$y=$_; 
                 while( $y ne $x) 
                 { $z=~s/(^[^\n]+?\s+##########.*?$)(.+?)\K(\1\n)//gmse ; $x=$y ;$y=$z } ; 
                 print "$z" '

用给定的输入

代码语言:javascript
复制
$ 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'

$
票数 2
EN

Stack Overflow用户

发布于 2019-03-03 19:54:50

每当我想到匹配模式和选择性打印时,我都会想到实用的提取和报告语言: Perl!这里有一个Perl一行程序,它能满足您的要求。您应该能够将其复制粘贴到shell中,并使其工作:

代码语言:javascript
复制
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,为了清晰起见,使用了换行符和注释(注意:这是不可执行的):

代码语言:javascript
复制
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解释器的系统上运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54972535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档