使用 sed 提取文本文件以删除另一个文件中按行给出的后缀
Posted
技术标签:
【中文标题】使用 sed 提取文本文件以删除另一个文件中按行给出的后缀【英文标题】:Stemming a text file to remove suffixes given linewise in another file using sed 【发布时间】:2021-11-14 11:45:21 【问题描述】:我有一个文件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
【问题讨论】:
【参考方案1】:有点麻烦,但仅限 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 for \b
。
使用 perl、ruby、awk 等会更容易
这是一个 GNU awk:
gawk -i join 'FNR==NR arr[FNR]=$1; next
FNR==1re=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
【讨论】:
实际上这并没有提供所需的输出。 您可能没有使用 GNU sed。【参考方案2】:你可以试试这个sed
方法。
您首先需要从suffix.txt
创建一个数组
suffix=($(cat suffix.txt))
然后您可以在主 sed
代码中使用它进行替换。
sed " s/$suffix[0]//;s/$suffix[1]//g;/question/! s/$suffix[2]//;s/$suffix[3]//g;/question/! s/$suffix[4]//" 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
【讨论】:
对不起,这至少对我来说似乎不对,对于这个例子,它似乎是硬编码的,而且你在哪里确保 suffix.txt 中的字符串(即后缀数组)实际上是在这个词的结尾?【参考方案3】:一个 awk:
$ awk '
NR==FNR # generate a regex of suffices
s=s (s==""?"(":"|") $0 # (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
【讨论】:
【参考方案4】:这可能对你有用(GNU sed):
sed -z 'y/\n/|/;s/|$//;s#.*#s/\\B(&)\\b//g#' suffixFile | sed -Ef - textFile
将 suffixFile 转换为文件中的 sed 命令,并通过管道将其传递给修改 textFile 的第二次 sed 调用。
注意sed 命令使用\B
和\b
来匹配后缀。
【讨论】:
谢谢,它成功了,但是你能解释一下你的代码吗?以上是关于使用 sed 提取文本文件以删除另一个文件中按行给出的后缀的主要内容,如果未能解决你的问题,请参考以下文章