for term in `cat stopwords`; do sed -i 's/\<$term\>//g' spam.txt ;done
鉴于停用词包含每行一个单词而spam.txt是纯文本文件,我只需要替换停用词的完全匹配。不像我期望的那样......
请注意,两个文件中都有doesn't
,couldn't
等字词。
答案 0 :(得分:8)
你确定要在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
答案 1 :(得分:8)
你应该在你的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
我的2美分
答案 2 :(得分:3)
@kerolasa正在那里。
最重要的是你的$ term不会被扩展为变量。您可以将代码重写为
for term in `cat stopwords`; do sed -i "s/\<${term}\>//g" spam.txt ;done
但这是一个非常昂贵的操作,你正在为stopwords
中的每个单词运行sed。根据@kerolasa创建一个sed脚本更有效,但这取决于,如果这是一次性项目,那么您的解决方案将起作用。
除了......“像这样的词,不能在两个文件中”,是的,和?我不确定你在那里说什么,你期望/想要发生什么,为什么你认为它不会发生?改变你的报价将有所帮助。
最后请注意,如果您的禁用词列表包含空格,即“工作中的扳手”;-),此解决方案可能会中断。
我希望这会有所帮助。
答案 3 :(得分:2)
您可以将脚本移至sed
,而不是使用Sami Kerola建议的脚本临时文件,使用stopwords
的第二个实例从sed
创建脚本}:
sed 's,.*,s/\\<&\\>//g,' stopwords | sed -i -f- spam.txt
请注意,我使用,
代替/
作为sed
的第一个实例的分隔符,而不必引用我在生成的表达式中用作分隔符的每个/
。但这只是一个品味问题,当然如果你更喜欢它,你也可以使用's/.*/s\/\\<&\\>\/\/g/'
。