如何使用shell脚本从两个句子中删除重复的单词?

Abd*_*_98 6 unix bash shell uniq

我有两个句子包含重复的单词,例如,文件中的输入数据my_text.txt

Unix 和 Linux 操作系统。
Unix 和 Linux 系统是为了创造一个促进高效程序的环境。

我使用了这个脚本:

while read p
do
echo "$p"|sort -u | uniq
done < my_text.txt
Run Code Online (Sandbox Code Playgroud)

但输出与输入文件的内容相同:

Unix 和 Linux 操作系统。Unix 和 Linux 系统是为了创造一个促进高效程序的环境

如何从两个句子中删除重复的单词?

tri*_*eee 4

您的代码将删除重复的行;sortuniq按线条操作,而不是文字。(即使如此,循环也是多余的;如果您想这样做,您的代码应该简化为sort -u my_text.txt。)

通常的解决方法是将输入拆分为每行一个单词;现实世界的文本有一些复杂性,但第一个基本的 Unix 101 实现看起来像

tr ' ' '\n' <my_text.txt | sort -u
Run Code Online (Sandbox Code Playgroud)

当然,这会以与原始顺序不同的顺序提供单词,并保存每个单词的第一次出现。如果您想丢弃任何多次出现的单词,也许可以尝试

tr ' ' '\n' <my_text.txt | sort | uniq -c | awk '$1 == 1 { print $2 }'
Run Code Online (Sandbox Code Playgroud)

(如果您tr不能识别\n换行符,也许可以尝试'\012'。)

这是一个非常简单的两遍 Awk 脚本,希望它更有用一点。它在第一次遍历文件时将所有单词收集到内存中,然后在第二次遍历时删除出现多次的所有单词。

awk 'NR==FNR { for (i=1; i<=NF; ++i) ++a[$i]; next }
{ for (i=1; i<=NF; ++i) if (a[$i] > 1) $i="" } 1' my_test.txt my_test.txt
Run Code Online (Sandbox Code Playgroud)

这会在单词被删除的地方留下空白;通过final 解决这个问题应该很容易sub()

一个更有用的程序会拆分所有标点符号,并将单词减少为小写(这样WordwordWord!、 和word?不会被视为单独的)。