Bash Sed就地编辑 用于“cat stopwords”中的术语;do sed-i的//\//g'spam.txt;完成

Bash Sed就地编辑 用于“cat stopwords”中的术语;do sed-i的//\//g'spam.txt;完成,bash,sed,Bash,Sed,假设stopwords每行包含一个单词,spam.txt是纯文本文件,我只需要替换stopwords的精确匹配项。行为不像我期望的那样。。。 注意,这两个文件中都有类似于不,不能的词。是否确实要在for循环中运行sed?我会使用sed脚本文件 for term in `cat stopwords`; do sed -i 's/\<$term\>//g' spam.txt ;done 您应该在sed命令中使用“而不是”。使用单引号”告诉shell不要替换$term 这: TMPFIL

假设stopwords每行包含一个单词,spam.txt是纯文本文件,我只需要替换stopwords的精确匹配项。行为不像我期望的那样。。。
注意,这两个文件中都有类似于
不能
的词。

是否确实要在for循环中运行sed?我会使用sed脚本文件

for term in `cat stopwords`; do sed -i 's/\<$term\>//g' spam.txt ;done
您应该在sed命令中使用“而不是”。使用单引号”告诉shell不要替换$term

这:

TMPFILE=mktemp
for WORD in $(cat stopwords); do echo 's/'$WORD'//g' >> $TMPFILE; done
sed -f $TMPFILE spam.txt
rm -f $TMPFILE
以及:

#spam.txt

foo@kerolasa发现了什么

最重要的是$term没有被扩展为变量

# spam.txt
foo <couldn't> bar
对于'cat stopwords'中的术语;do sed-i“s/\//g”spam.txt;完成
但这是一个非常昂贵的操作,您要为
stopwords
中的每个单词运行sed。根据@kerolasa idea制作sed脚本效率更高,但这取决于,如果这是一个一次性项目,那么您的解决方案将起作用

除了…“两个文件中都有“不”和“不能”这样的词”,是的,还有?我不确定你在说什么,你期望/想要发生什么,为什么你认为不会发生?改变你的引用会有所帮助

最后,请注意,如果停止字列表中包含空格,则此解决方案可能会中断,即“正在工作的扳手”;-)


我希望这会有所帮助。

您也可以将脚本通过管道传输到
sed
,使用
sed
的第二个实例,从
stopwords
创建脚本,而不是使用所建议的脚本临时文件:

for term in `cat stopwords`; do sed -i "s/\<${term}\>//g" spam.txt ;done
sed's,.*,s/\\//g,'stopwords|sed-i-f-spam.txt

请注意,我使用了
而不是
/
作为sed
的第一个实例的分隔符,这样就不必在生成的表达式中引用我用作分隔符的每个
/
。但这只是一个口味问题,当然,如果您更喜欢的话,您也可以使用
's/*/s\/\\\/\\/\\/\/g/'

我总是得到c与bash中的引号融合…并怀疑替换不正确。因此指出它…并且stopwords中没有空格。感谢指出它…我认为它更像l33t,只是做就地替换。但这是很好和优雅的…只是想知道这个答案中是否有错别字,我认为应该是
sed-I-f$TMPFILE spam.txt
-从而保持OP执行就地替换的意图,只是更有效地使用脚本文件。我们可以使用
sed
生成
$TMPFILE
sed's | | s/| s |$/g | stopwords>$TMPFILE
。然后直接将其作为脚本使用:
sed's | | ^ ^ ^ ^ ^ ^ ^ ^ s/| s$/g |d-i-f-spam.txt
@aragaer:这基本上是复制到评论中的。@sh lecram:对不起,我没有注意到这个答案。但是这个技巧太酷了,我现在经常自己使用它。
# spam.txt
foo <couldn't> bar
for term in `cat stopwords`; do sed -i "s/\<${term}\>//g" spam.txt ;done
sed 's,.*,s/\\<&\\>//g,' stopwords | sed -i -f- spam.txt