如何从文本文件中删除所有出现的单词列表?

如何从文本文件中删除所有出现的单词列表?

我有一个包含单词列表的文件。我想从一个大文本文件中删除此文件中所有单词的所有出现。

例子:

文件1

queen
king

文本文件样本

Both the king and queen are monarchs. Will the queen live? Queen, it is!

这是我尝试过的:

sed -i 's/queen/ /g' page.txt
sed -i 's/Queen/ /g' page.txt

输出

Both the and are monarchs. Will the live? , it is!

我的单词列表很大(超过 50000 个单词)。如何在无需在命令行中指定模式的情况下执行此操作?

答案1

对于您的实际用例,我建议terdon 使用 Perl 的回答

然而,简单的版本,不处理其他单词的子串(例如,从“hiking”中删除“king”),是使用一个 Sed 命令生成由不同 Sed 实例运行的命令在您的实际文件上。

在这种情况下,wordfile包含“国王”和“女王”并textfile包含您的文本:

sed -e "$(sed 's:.*:s/&//ig:' wordfile)" textfile

请注意,“i忽略大小写”标志是 GNU 扩展,而不是标准。

答案2

简单但低效的方法是多次处理文件,每个输入单词处理一次:

$ while read w; do sed -i "s/$w//ig" file2 ; done < file1
$ cat file2
Both the  and  are monarchs. Will the  live? , it is!

不过,对于大文件来说,这可能会非常慢(并且还匹配子字符串)。您可以使用 Perl 一次性完成此操作:

perl -lpe 'BEGIN{open(A,"file1"); chomp(@k = <A>)} 
                 for $w (@k){s/\b\Q$w\E\b//ig}' file2 

确保\b我们只匹配单词边界,\Q\E确保$w按字面意思理解。这将阻止脚本匹配hiking,但它仍然会匹配high-king。为了避免这种情况,您需要明确列出定义单词的字符:

perl -Mopen=locale -Mutf8 -lpe '
  BEGIN{open(A,"file1"); chomp(@k = <A>)} 
  for $w (@k){s/(^|[ ,.—_;-])\Q$w\E([ ,.—_;-]|$)/$1$2/ig}' file2 

上面的非 ASCII字符需要以 UTF-8 编码形式输入,因为我们告诉perl代码是用 UTF-8 编写的-Mutf8。我们使用-Mopen=locale文件的内容和标准输出在区域设置的字符集中进行解码/编码。

答案3

将此脚本保存到文件d:(从 GITHUB 下载 GIST

#!/bin/bash

LIST=${1:?"LIST word"}
FILE=${2:?"FILE name not set"}

L=$( sed -e ':a;N;$!ba;s_\n_\x00_g' ${LIST}|sed -e 's_\x00_ \\|_g' -e's_\(\\|\)*$__g')
P='s_\('$L'\)__ig'
O="sed -e '$P'  ${FILE}"

eval "${O}"

然后运行它:

bash ./d LIST FILE 

如果你想保存文件,你可以运行这个命令:

bash ./d LIST FILE  | tee NewFILE

或者

bash ./d LIST FILE > NewFile

我阅读 LIST WORD 并将其更改为正则表达式格式,例如我将您的queenandking更改test为以下格式:

queen\|king\|test

然后sed使用此参数创建命令:

sed -e 's_\(queen\|king\|test\) *__ig' FILE

使用这个 bash 脚本,我们一次LISTWORD又一次地读取FILE以进行替换

相关内容