【问题标题】:Grep (a.txt - En word list, b.txt - one string in each line) Q: string from b.txt built only from words or not?Grep (a.txt - En word list, b.txt - 每行一个字符串) 问:b.txt 中的字符串是否仅由单词构建?
【发布时间】:2014-04-03 17:17:43
【问题描述】:

我有一个包含英文单词的列表(每行 1 个,大约 100.000)-> a.txt 和 b.txt 包含字符串(大约 50.000 行,每行一个字符串,可以包含纯单词,word+something , 垃圾)。我想知道 b.txt 中的哪些字符串只包含英文单词(没有任何额外的字符)。

我可以用grep 做到这一点吗?

例子:

a.txt:

apple
pie

b.txt:

applepie
applebs
bspie
bsabcbs

输出:

c.txt:

applepie

【问题讨论】:

  • 更加详细。目前,您的问题的解决方案是echo "applepie" > c.txt。这可能不是你想要的。我们不喜欢猜测或给出答案。
  • 简短的回答是否定的,仅使用grep 是不可能的。您需要根据a.txtb.txt 手动匹配每个可能的排列。
  • 您的编辑使这项工作变得更加复杂。并非a.txt 中的每个单词排列都是有效的英语复合词,因此您所要求的甚至无法解决您的问题(根据您的示例,您的单词表不包含复合词)。即使您要这样做,您也需要构建一个排列列表,考虑到文件的大小,需要一种复杂的表示形式,否则您将遇到内存问题(某种树)。这不是您想用 shell 脚本解决的问题。您的问题确实没有简单的答案。

标签: string bash grep


【解决方案1】:

由于您的问题未详细说明,也许这个答案可以帮助您在黑暗中澄清您的问题:

c='cat b.txt'
while IFS='' read -e line
do
  c="$c | grep '$line'"
done < a.txt
eval "$c" > c.txt

但这也将匹配this is my apply on a pie 之类的行。不知道是不是你想要的。

这是另一个尝试:

re=''
while IFS='' read -e line
do
  re="$re${re:+|}$line"
done < a.txt
grep -E "^($re)*$" b.txt > c.txt

这将只让那些只有这些单词串联的行通过。但它也会让诸如“appleapplepieapplepiepieapple”之类的东西通过。再说一次,我不知道这是否是你想要的。

鉴于您对问题的最新解释,我会提出另一种方法(因为用 100000 多个单词构建这样的列表是行不通的)。

处理这么多单词的一种可行方法是从文本中删除所有已识别的单词,并查看在此过程中哪些行被清空。这可以很容易地迭代完成,而不会爆炸内存使用或其他资源。不过这需要时间。

cp b.txt inprogress.txt
while IFS='' read -e line
do
  sed -i "s/$line//g" inprogress.txt
done < a.txt
for lineNumber in $(grep -n '^$' inprogress.txt | sed 's/://')
do
  sed -n "${lineNumber}p" b.txt
done
rm inprogress.txt

但这仍然不能真正解决您的问题;考虑一下您的列表中是否有 topotato 两个词,并且首先会删除 to,那么这将在您的文本文件中留下一个词 pota,而 pota 不是一个词然后将被删除。

您可以通过按单词长度(最长单词优先)对单词文件进行排序来解决该问题,但在某些复合词的情况下,这仍然会出现问题,例如。 G。 redart(为red + art)但dart 将首先被删除,所以re 将保留。如果那不在您的单词列表中,您将无法识别该单词。

实际上,您的问题是逻辑编程和自然语言处理之一,可能不适合 SO。您应该看看针对您的问题设计的语言 Prolog

【讨论】:

  • 我还是觉得这个不好解决;显然 OP 的单词列表不包含复合词,因此不可能建立一个有效复合词列表来匹配另一个文件。
  • 你说的很对,100000 字在这个列表中爆炸了很多方法。但也许接近解决方案的东西对 OP 来说就足够了。否则他应该使用不同于grep的东西。
【解决方案2】:

我也会将此作为答案发布,因为我认为这是对您的具体问题的正确答案。

您的要求是根据包含英语单词列表的单词列表 (a.txt) 在文件 (b.txt) 中查找非英语单词。根据您问题中的示例,说单词列表不包含复合词(例如applepie),但您仍然希望根据您的单词列表中的单词将文件与复合词匹配(例如applepie) .

你面临两个问题:

  1. 并非a.txt 中的每个单词排列都是有效的英语复合词,因此仅基于此,您的问题已经无法解决。

  2. 如果您仍然尝试通过编译所有可能排列的列表来自己构建复合词列表,那么由于您的单词列表的大小(以及由此产生的记忆问题),您将无法轻易做到这一点。您很可能必须将您的单词存储在更复杂的数据结构中,例如一棵树,并通过遍历树来动态构建排列,这在 shell 脚本中是不可行的。

由于这些要点以及您的实际问题是“这可以用grep 完成吗?”答案是否定的,这是不可能的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 2019-08-06
    • 2020-03-22
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多