Bash + Filter,删掉整个句子

时间:2016-04-14 22:56:51

标签: python bash awk sed grep

输入(文件):

This is something word1 delete
Another sentence word2d continuation
Should we remove this?
Let leave untouched
Also that is word1 let it stay
So this word1 delete also
word3 del this line should be also deleted
Please YDeTeLe me

过滤器(文件):

word1 delete
this
word2d
word3 del
detele

期望的输出:

Let leave untouched  
Also this word1 let it stay  

我看到了一些awk解决方案,其中filter与具体记录相关联,但是当过滤器中的字符串不在特定位置时如何过滤掉。

简单地说,如果过滤器文件中的行是main(输入)文件中的行的子串,那么该行应该被过滤掉。

我有python解决方案,在python中易于实现的想法,仍然很好奇,awk oneliner可以证明概念验证,就像在某些情况下awk优于python一样。

import codecs

lmyfilter = []
ffilter = codecs.open('filter', 'r', 'utf-8')
for line in ffilter:
    line = line.strip('\n')
    lmyfilter.append(line)
ffilter.close()

finput = codecs.open('input', 'r', 'utf-8')
for line in finput:
        line = line.strip('\n')
        letitpass = True
        for filteritem in lmyfilter:
            if filteritem.lower().strip('!"&\'()*,-./:;?<>[\]_{}«·»‑–—―‖‘’“”…′$#') in line.lower():
                letitpass = False
        if letitpass:
            print(line)
finput.close()  

根据Ed's猎鹰的眼睛,我将不得不增加新的要求:
 *案例敏感性已关闭  *解决方案需要基于utf-8  *要忽略的单词左侧或右侧的标点符号
 *现在不严格要求awk,但命令行解决方案是

3 个答案:

答案 0 :(得分:1)

awk救援!

$ awk 'NR==FNR{fs[$0]; next}
              {for(f in fs) if($0~f) next; print}' filter file    

Let leave untouched  
Also this word1 let it stay

答案 1 :(得分:1)

如果过滤器文件维护良好(理想情况下是通过一些自动化 - 如果手动完成,请确保没有尾随空格或DOS回车,没有拼写错误,没有注释,所有正则表达式特殊文件都被正确转义,等等)您只需将其转换为sedgrep -E脚本即可。

tr '\n' '|' <filter |
sed 's/\|$//;s/.*/(^|[^[:alnum:]])(&)([^[:alnum:]]|$)/' |
grep -Evif - input

字符类[^[:alnum:]]可能与“标点符号”完全不同,但有了这个级别的要求,我会留给您更详细地说明这一点。也许可以尝试使用\<\>

tr完成了在一行上通过|字符加入过滤器表达式的基本工作。 sed在基本过滤器表达式周围添加了正则表达式上下文,以将其约束为(类似)孤立的单词。然后,我们使用合适的选项将生成的表达式提供给grep -Ef -以删除具有匹配项的任何行,不区分大小写。

以下是对Python代码的重构:

#!/usr/bin/env python3

import codecs, re

with codecs.open('filterfile', 'r', 'utf-8') as ffilter:
    lmyfilter = [line.strip('\n') for line in ffilter]

puncsp = r'[][\s!"&\'()*,-./:;?<>\_{}«·»‑–—―‖‘’“”…′$#]'
regex = re.compile(r'(?:^|' + puncsp + r')(' + '|'.join(lmyfilter) +
    r')(?:' + puncsp + r'|$)', re.IGNORECASE + re.LOCALE + re.UNICODE)

with codecs.open('inputfile', 'r', 'utf-8') as finput:
    for line in finput:
        line = line.strip('\n')
        if regex.search(line):
            continue
        print(line)

答案 2 :(得分:1)

此类问题的常见解决方案是

grep -vif filter input.txt

然而,这也删除了行

  

此词也让它留下来

包含模式this。您想在使用后丢弃每个模式吗?