【问题标题】:Using sed to remove words in a stopword list (Feeding sed a list of parameters to remove from a text file)使用 sed 删除停用词列表中的单词(为 sed 提供要从文本文件中删除的参数列表)
【发布时间】:2013-01-22 13:11:42
【问题描述】:

所以,我们都知道 sed 非常擅长查找和替换文件中所有出现的单词:

sed -i 's/original_word/new_word/g' file.txt

但是,有人可以告诉我如何从文件中为 sed 提供“original_words”列表(类似于 grep -f)吗?我只想用 '' 替换所有(删除它们)。

原来的wordlist文件只是一堆用行分隔的停用词(wordlist.txt):

a
about
above
according
across
after
afterwards

这将是一种获取停用词列表并从语料库中删除它们的简单方法(对于清理数据很有用)。

file.txt 看起来像

05ricardo   RT @shakira: Immigration reform isn't about politics. It's about people mothers, kids. Obama is working for all of them. http://t.co/rAW ...    0
05ricardo   ?@ItsReginaG: Don't vote Obama. Because you will lose jobs, and die.? Lol   0
05ricardo   ?@shakira: Obama doubles Pell Grants - 700,000 more Latinos get help to go to college. Meet Johanny Adames http://t.co/EMg8NLGl Shak?. ?    -1
05rodriguez_a   My Comm teacher gave me a copy of Obama's speech that he gave the other night and I cried while reading it. It was that moving. -3

【问题讨论】:

标签: unix sed awk grep


【解决方案1】:

也许是这样

#!/bin/sh
while read k
do
  sed -i "s/$k//g" file.txt
done < dict.txt

【讨论】:

  • sed: 1: "file.txt": 无效的命令代码 S。不确定它是否喜欢 $k。
  • 对不起。我已经添加了。
【解决方案2】:

这是使用GNU sed的一种方式:

while IFS= read -r word; do sed -ri "s/( |)\b$word\b//g" file; done < wordlist

文件内容:

how about I decide to look at it afterwards. What
across do you think? Is it a good idea to go out and about? I 
think I'd rather go up and above.

结果:

how I decide to look at it. What
 do you think? Is it good idea to go out and? I 
think I'd rather go up and.

【讨论】:

  • 感谢您的评论!它不喜欢我的 -r:sed: 非法选项 -- r
  • 是的,很遗憾,您似乎没有使用GNU sed。您可能在 OSX 上使用BSD sed。如果您删除 -r 标志,则需要删除单词边界 (\b)。
  • 我确实是。谢谢你。对于任何运行 GNU 的人来说,这都是一个很好的解决方案。
  • 对每个停用词调用一次sed 效率极低,尤其是在停用词列表很大且文件很大的情况下。
【解决方案3】:

首先,并非所有sed 都支持-i,但这不是必需的选项,因为以一般方式提供该功能是微不足道的。一个简单的选择(假设一个非 csh 系列的 shell):

inline() { f=$1; shift; "$@" < $f > $f.out && mv $f.out $f; }

然后,进行替换(您尚未指定要如何处理单词分隔符,因此如果“foo”在黑名单中,“bar foo baz”将在“bar”和“之间有两个空格baz") 使用 awk 或 perl 都非常简单:

awk 'NR==FNR{a[$0]; next} {for( i in a ) gsub( i, "" )} 1' original-words file.txt
perl -wne 'if( $ARGV = $ARGV[0] ){ chop; push @no, $_; next } 
    foreach $x( @no ) {s/$x//g } print ' original-words file.txt

如果您对结果感到满意,请使用-iperl(并非所有sed 都支持-i,但所有perl > 5.0),或者您可以使用以下命令修改文件:

inline file.txt awk 'NR==FNR{a[$0]; next} 
    {for( i in a ) gsub( i, "" )} 1' original-words -

这些解决方案中的任何一个都将比为黑名单中的每个单词调用 sed 快得多。

【讨论】:

    【解决方案4】:

    您也可以让 sed 为您编写 sed 脚本(使用 GNU sed 测试):

    <stopwords sed 's:.*:s/\\b&\\b//:g' | sed -f - file.txt
    

    输出:

    05ricardo   RT @shakira: Immigration reform isn't  politics. It's about people mothers, kids. Obama is working for all of them. http://t.co/rAW ...    0
    05ricardo   ?@ItsReginaG: Don't vote Obama. Because you will lose jobs, and die.? Lol   0
    05ricardo   ?@shakira: Obama doubles Pell Grants - 700,000 more Latinos get help to go to college. Meet Johanny Adames http://t.co/EMg8NLGl Shak?. ?    -1
    05rodriguez_a   My Comm teacher gave me  copy of Obama's speech that he gave the other night and I cried while reading it. It was that moving. -3
    

    【讨论】:

    • 请注意,Apple OS X sed 不支持从标准输入 (sed -f -) 读取脚本。所以你必须先将命令写入文件
    • @Otto:你是对的,所以这只是一个 GNU sed,除非编写了一个临时脚本文件。谢谢。
    【解决方案5】:
    cat file.txt | grep  -vf wordlist.txt
    

    【讨论】:

    • 这将删除包含任何停用词的行,而不仅仅是删除停用词。
    • 它也会匹配部分单词,所以如果a是一个停用词,那么剩下的就不多了...
    • 我不确定,但也许-x 可以解决这个问题。
    猜你喜欢
    • 2017-06-21
    • 2018-09-28
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 2021-02-02
    相关资源
    最近更新 更多