使用 grep 或 sed 仅保留另一个单词列表文件中的单词

Posted

技术标签:

【中文标题】使用 grep 或 sed 仅保留另一个单词列表文件中的单词【英文标题】:Use grep or sed to keep only the words that are in another word list file 【发布时间】:2021-11-17 08:15:37 【问题描述】:

我有一个句子列表(每行一个句子)和一本字典(一个单词列表,每行一个单词)。我想使用 awk、grep 或 sed 来编辑句子文件,以便只保留我的字典文件中的单词。 例如字典:

hello
dog
lost
I
miss
computer
buy

输入文件:

I miss my dog
I want to buy a new computer

结果:

I miss dog
I buy computer

我知道这可以通过 Python 轻松完成,但我尝试使用终端命令(awk、sed、grep 或任何其他终端命令)。

谢谢。

【问题讨论】:

你会如何在 python 中做到这一点?使其适应 awk。 我知道 Python,但我是 awk、sed、grep 等的初学者并尝试使用它们。在 Python 中,我只需读取单词列表文件,使用单词创建一个字符串列表,然后读取输入文件并输出该单词(如果它存在于数组中)。 请提供足够的代码,以便其他人更好地理解或重现问题。 【参考方案1】:

这是作为伪代码的基本算法。我建议尝试使用 AWK 来实现它:

if (condition) statement [ else statement ] 

while (condition) statement

do statement while (condition)

for (expr1; expr2; expr3) statement

for (var in array) statement

break

continue

【讨论】:

【参考方案2】:

在 Python 中,我只需读取单词列表文件,使用单词创建一个字符串列表,然后读取输入文件并输出该单词(如果它存在于数组中)。

这也是你在awk 中的做法:

$ awk 'FNR == NR  dict[$0] = 1; next  # Read the dictionary file
        # And for each word of each line of the sentence file
         for (word = 1; word <= NF; word++) 
           if ($word in dict) # See if it's in the dictionary
             printf "%s ", $word
         
         printf "\n"
       ' dict.txt input.txt
I miss dog
I buy computer

(这确实会在每一行留下一个尾随空格,但如果重要的话很容易过滤掉)

【讨论】:

【参考方案3】:
awk '
    NR==FNR  dict[$1]; next 
    
        sent = ""
        for (i=1; i<=NF; i++) 
            if ($i in dict) 
                sent = (sent=="" ? "" : sent OFS) $i
            
        
        print sent
    
' dict file
I miss dog
I buy computer

三元表达式(sent=="" ? "" : sent OFS) 是为了确保我们不会在将要输出的句子的开头或结尾得到一个虚假的空白字符,如果已经有另一个前面的单词,则只在当前单词之前添加一个空格。

以上假设匹配应该区分大小写。如果不是,则将dict[$1] 更改为dict[tolower[$1]] 并将$i in dict 更改为tolower($i) in dict。它还假设没有要考虑的标点符号,例如I miss my dog.my dog's friendly。如果这是错误的,请编辑您的问题以提供包含标点符号的示例输入/输出。

【讨论】:

【参考方案4】:

这可能对你有用(GNU sed):

sed -E 'H;$!d;x;s/.//;y/\n/|/;s/.*/s#\\b(&)\\b#\\n\&#g/' dictionaryFile |
sed -Ef - -e 's/^(\S+).*/\1/mg;s/\n/ /g;s/.//' textFile

dictionaryFile 制作成一个 sed 命令文件,该文件在该文件中的每个单词前面加上一个换行符。

在第二次调用 sed 时,使用从第一次调用通过管道传输的 sed 命令文件,然后使用多行替换,删除一行中第一个单词之后的所有内容。

用空格替换换行符并删除行首的第一个空格并打印结果。

可以通过在第二个 sed 调用命令中添加 /\S/!d 来消除空行。

【讨论】:

以上是关于使用 grep 或 sed 仅保留另一个单词列表文件中的单词的主要内容,如果未能解决你的问题,请参考以下文章

使用 sed 时转义“./”

使用 sed/awk 仅打印包含匹配模式的单词 - 以 /pattern/ 开头或以 /pattern/ 结尾的单词

如何使用 sed/grep 提取两个单词之间的文本?

如何使用 grep 命令获取连续有六个或更多辅音的单词列表?

是否可以使用 grep 或 find 命令替换仅给出前几个和最后几个单词的给定字符串

多个模式的一个参数 - grep