【问题标题】:GREP in part of line using keywords file使用关键字文件的部分行中的 GREP
【发布时间】:2016-11-15 01:12:12
【问题描述】:

我需要检查 txt 文件中的多个短语,如果文件在特定行中包含它们,请从 txt fie 中删除该行。

对包含需要删除的短语的文件使用反向 grep 可以作为一种魅力。

问题是我需要搜索每行的一部分,而不是整行。

我只需要检查第 10 个逗号字符之前的部分行。 如果 grep 找到之后的短语,我想保留该行,如果 grep 在该点之前匹配,我想删除该行。

我不知道如何将正则表达式与短语文件一起使用。欢迎任何建议。

#!/bin/bash 

shopt -s globstar

for f in /uploads/txt/original/**/*.txt ; do

  grep -i -v -w -f phrase.txt "$f" > tmp
  mv tmp $f

done  

echo "Finished!"

编辑

   # Rule to set the flag if the line needs to be printed or not
{
    ok = 1
    # loop upto tenth column
    for (i = 1; i <= 10; i++){
        # match against each pattern
        for (p in PATS) {
            if ($i ~ p) {
                ok = 0
            }
        }
    }
}

这是否意味着每一列都会再次运行 PATS?

是否可以将 10 列合并到一个字符串中,然后再次检查所有模式,而不是针对所有模式检查 10 列?

【问题讨论】:

  • 你能用grep -i -v -w -f phrase.txt &lt;(cat /uploads/txt/original/**/*.txt)避免循环吗?
  • @WalterA not sure how cut line is phrase.txt 在这种情况下会有所帮助,因为我需要在 txt 文件中搜索部分行,而不是在包含我的短语的短语.txt 中在那些 txt 文件中搜索。
  • 混合了文件。您可以在
  • @JayRajput 你能看看问题的编辑部分吗?我正在尝试提高速度并尝试了解它当前的工作原理

标签: linux bash grep


【解决方案1】:

输入数据/tmp/test

Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9, Col10, Col11, Col12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
FOO,  Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
FOO1,  Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
foo,  Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
Val1, BAR,  Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, FOO,   Val12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, BAR,   Val12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, FOO,   Val11, Val12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, BAR,   Val11, Val12

短语/tmp/短语

FOO
BAR

带有 cmets 的 Awk 脚本

#!/usr/bin/gawk -f

BEGIN {
    FS         = " *, *" # Field Separator regex to split words
    IGNORECASE = 1       # ignore case for regex match

    # read phrases file in an array
    # prepend '^' and append '$' to the phrase for exact match
    while (getline a < "/tmp/phrases") PATS["^"a"$"]
}

# Rule to set the flag if the line needs to be printed or not
{
    ok = 1
    # loop upto tenth column
    for (i = 1; i <= 10; i++){
        # match against each pattern
        for (p in PATS) {
            if ($i ~ p) {
                ok = 0
            }
        }
    }
}

# Rule to actual print if flag is set
ok {print}

# Debugging rule. Get rid for actual code.
END { for (p in PATS) print p }

# One liner
#  gawk 'BEGIN{FS=" *, *";IGNORECASE=1;while(getline a < "/tmp/phrases")PATS["^"a"$"]}{ok=1;for(i=1;i<=10;i++){for(p in PATS){if($i ~ p){ok=0}}}} ok {print}' /tmp/test

输出:

Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9, Col10, Col11, Col12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
FOO1,  Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, FOO,   Val12
Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, BAR,   Val12

归功于这个答案https://stackoverflow.com/a/14471194/2032943

【讨论】:

  • 伟大而详细的答案,虽然第 10 个字符,我的意思是第 10 个特定字符,我不知道字符串中的距离,所以 substr 在这里不起作用。例如:我的、线条、看起来、像、这个、有很多不同的文本,但我只想检查第 10 个昏迷字符。也不能用正则表达式包装 p ,因为我的文本文件只包含短语而不包含正则表达式模式本身。我希望正则表达式不区分大小写并查找整个单词/短语。
  • 谢谢,完美运行,比 grep 慢得多,但保存了 dat。我在哪里可以找到所有 gawk 选项?
  • awk 的 GNU 手册非常好而且很详细。我通常会查看 Oreilly 的书或 google 以获取有关 awk 的帮助。如果您看到性能问题,您可能希望切换到 python 并更快地完成它。由于所有这些 for 循环,awk 很慢。
  • 我遇到了另一个问题。可能我没有在我的问题中正确指定它。在这种情况下有效:FOO, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12 当关键字是句子的一部分时不起作用。 FOO some other text, Val2, Val3, Val4, Val5, Val6, Val7, Val8, Val9, Val10, Val11, Val12 有什么建议吗?
猜你喜欢
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多