使用 grep 或 sed 只保留另一个单词列表文件中的单词
Use grep or sed to keep only the words that are in another word list file
我有一个句子列表(每行一个句子)和一个字典(一个单词列表,每行一个单词)。我想使用 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 或任何其他终端命令)。
谢谢。
这是作为伪代码的基本算法。我建议尝试使用 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
In Python I would just read the word list file, create a list of strings with the words, then read the input file and output the word if it exists in the array.
这也是您在 awk
中的做法:
$ awk 'FNR == NR { dict[[=10=]] = 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
(这确实会在每一行留下一个尾随的 space,但如果重要的话很容易过滤掉)
awk '
NR==FNR { dict[]; 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[]
更改为 dict[tolower[]]
,将 $i in dict
更改为 tolower($i) in dict
。它还假设没有标点符号需要考虑,例如I miss my dog.
或 my dog's friendly
。如果那是错误的,请编辑您的问题以提供包含标点符号的示例 input/output。
这可能适合您 (GNU sed):
sed -E 'H;$!d;x;s/.//;y/\n/|/;s/.*/s#\b(&)\b#\n\&#g/' dictionaryFile |
sed -Ef - -e 's/^(\S+).*//mg;s/\n/ /g;s/.//' textFile
将 dictionaryFile
制作成一个 sed 命令文件,它会在该文件中的每个单词前加上一个换行符。
在第二次调用 sed 时,使用从第一次调用管道传输的 sed 命令文件,然后使用多行替换,删除一行中第一个单词之后的所有内容。
用 spaces 替换换行符并删除行首的第一个 space 并打印结果。
可以通过在第二个 sed 调用命令中添加 /\S/!d
来消除空行。
我有一个句子列表(每行一个句子)和一个字典(一个单词列表,每行一个单词)。我想使用 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 或任何其他终端命令)。
谢谢。
这是作为伪代码的基本算法。我建议尝试使用 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
In Python I would just read the word list file, create a list of strings with the words, then read the input file and output the word if it exists in the array.
这也是您在 awk
中的做法:
$ awk 'FNR == NR { dict[[=10=]] = 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
(这确实会在每一行留下一个尾随的 space,但如果重要的话很容易过滤掉)
awk '
NR==FNR { dict[]; 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[]
更改为 dict[tolower[]]
,将 $i in dict
更改为 tolower($i) in dict
。它还假设没有标点符号需要考虑,例如I miss my dog.
或 my dog's friendly
。如果那是错误的,请编辑您的问题以提供包含标点符号的示例 input/output。
这可能适合您 (GNU sed):
sed -E 'H;$!d;x;s/.//;y/\n/|/;s/.*/s#\b(&)\b#\n\&#g/' dictionaryFile |
sed -Ef - -e 's/^(\S+).*//mg;s/\n/ /g;s/.//' textFile
将 dictionaryFile
制作成一个 sed 命令文件,它会在该文件中的每个单词前加上一个换行符。
在第二次调用 sed 时,使用从第一次调用管道传输的 sed 命令文件,然后使用多行替换,删除一行中第一个单词之后的所有内容。
用 spaces 替换换行符并删除行首的第一个 space 并打印结果。
可以通过在第二个 sed 调用命令中添加 /\S/!d
来消除空行。