for term in `cat stopwords`; do sed -i 's/\<$term\>//g' spam.txt ;done
给定的停用词列表每行包含一个单词,而spam.txt是一个纯文本文件,我只需要替换停用词的精确匹配。但实际效果与我的预期不同......请注意,这两个文件中都有像doesn't
、couldn't
这样的单词。
您确定要在for循环中运行sed吗?我建议使用sed脚本文件。
TMPFILE=mktemp
for WORD in $(cat stopwords); do echo 's/'$WORD'//g' >> $TMPFILE; done
sed -f $TMPFILE spam.txt
rm -f $TMPFILE
很好,你应该在sed命令中使用“”而不是'。使用单引号 ' 告诉Shell不要替换$term。
这样写:
for term in `cat stopwords`; do sed -i "s/\<$term\>//g" spam.txt ;done
适用于:
# stopwords
couldn't
并且:
# spam.txt
foo <couldn't> bar
我的两分钱意见
@kerolasa的想法很有道理。
最重要的是,你的$term没有被扩展成变量。你可以将代码改写为
for term in `cat stopwords`; do sed -i "s/\<${term}\>//g" spam.txt ;done
stopwords
中的单词的sed。根据@kerolasa的想法制作sed脚本更有效,但这取决于情况,如果这是一个一次性的项目,那么你的解决方案将起作用。不要像Sami Kerola建议的那样使用临时文件,你也可以将脚本通过管道传输给sed
,使用第二个sed
实例从stopwords
中创建它:
sed 's,.*,s/\\<&\\>//g,' stopwords | sed -i -f- spam.txt
,
而不是/
作为分隔符,以避免在生成的表达式中引用每个作为分隔符的/
。但这只是个人口味问题,当然你也可以使用's/.*/s\/\\<&\\>\/\/g/'
,如果你更喜欢的话。请保留HTML标签。
sed -i -f $TMPFILE spam.txt
-从而保持原作者的意图进行原地替换,只是更高效地使用脚本文件。 - Peter Mulariensed
生成$TMPFILE
:sed 's|^|s/|;s|$|//g|' stopwords > $TMPFILE
。然后直接将其作为脚本使用:sed 's|^|s/|;s|$|//g|' stopwords | sed -i -f - spam.txt
。 - aragaertmpfile
,我建议使用 trap 来确保它被删除。 - mschilli