使用 sed 提取文本文件以删除另一个文件中按行给出的后缀

Stemming a text file to remove suffixes given linewise in another file using sed

我有一个文件suffix.txt,其中包含一些按行排列的字符串,例如-

ing
ness
es
ed
tion

此外,我有一个文本文件 text.txt,其中包含一些文本, 假设 text.txt 只包含小写字母且没有任何标点符号,例如-

the raining cloud answered the man all his interrogation and with all
questioned mind the princess responded
harness all goodness without getting irritated

我只想从 text.txt 中的原始单词中删除每个后缀一次的后缀。因此我期望以下输出-

the rain cloud answer the man all his interroga and with all
question mind the princess respond
har all good without gett irritat

请注意,tion 并未从 questioned 中删除,因为原始单词不包含 tion 作为后缀。如果有人可以用 sed 命令回答这个问题,那将非常有帮助。 我使用的是一个天真的脚本,它似乎无法完成这项工作-

#!/bin/bash

while read p; do
  sed -i "s/$p / /g" text.txt;
  sed -i "s/$p$//g" text.txt;
done <suffix.txt

有点毛茸茸,但仅限 sed 和 unix 工具:

sed -E -f <(tr '\n' '|' <suffix.txt | sed 's/\|$//; s/\|/\\b|/g; s/$/\\b/' | xargs printf 's/%s//g') text.txt

tr '\n' '|' <suffix.txt | sed 's/\|$//; s/\|/\\b|/g; s/$/\\b/' | xargs printf 's/%s//g'

生成

的替换脚本
s/ing\b|ness\b|es\b|ed\b|tion\b//g

这需要 GNU sed \b

使用 perl、ruby、awk 等会更容易

这是一个 GNU awk:

gawk -i join 'FNR==NR {arr[FNR]=; next}
FNR==1{re=join(arr,1,length(arr),"\>|"); re=re "\>"}
{gsub(re,"")}
1
' suffix.txt text.txt

两者都产生:

the rain cloud answer the man all his interroga and with all
question mind the princess respond
har all good without gett irritat

一个awk:

$ awk '
NR==FNR {                   # generate a regex of suffices
    s=s (s==""?"(":"|") [=10=]  # (ing|ness|es|ed|tion)$
    next
}
FNR==1 {
    s=s ")$"                # well, above )$ is inserted here
}
{
    for(i=1;i<=NF;i++)      # iterate all the words and
        sub(s,"",$i)        # apply regex to each of them
}1' suffix text             # output

输出:

the rain cloud answer the man all his interroga and with all
question mind the princess respond
har all good without gett irritat

这可能适合您 (GNU sed):

sed -z 'y/\n/|/;s/|$//;s#.*#s/\B(&)\b//g#' suffixFile | sed -Ef - textFile

将 suffixFile 转换为文件中的 sed 命令,并通过管道将其传递给修改文本文件的 sed 的第二次调用。

N.B。 sed 命令使用 \B\b 来匹配后缀。