sed:删除包含字符类的整个单词

时间:2014-08-06 11:02:57

标签: linux bash command-line awk sed

我想从文本文件中删除任何包含非alpha字符的单词。 e.g

"ok 0bad ba1d bad3 4bad4 5bad5bad5"

应该成为

"ok"

我尝试过使用

echo "ok 0bad ba1d bad3 4bad4 5bad5bad5" | sed 's/\b[a-zA-Z]*[^a-zA-Z]\+[a-zA-Z]*\b/ /g'

5 个答案:

答案 0 :(得分:4)

以下 sed 命令执行此任务:

sed 's/[[:space:]]*[[:alpha:]]*[^[:space:][:alpha:]][^[:space:]]*//g'

删除包含至少一个非字母字符的所有单词。最好使用像[:alpha:]这样的POSIX字符类,因为例如他们不会认为法语名称“François”有缺陷(即包含非字母字符)。

解释

我们删除所有模式,从任意数量的空格开始,后跟任意(可能是零)个字母字符,后跟至少一个非空格和非字母字符,然后选择glob到单词的末尾(即直到下一个空间)。请注意,您可能需要将[:space:]换成[:blank:],有关这两个POSIX类之间差异的详细说明,请参阅this page

测试

$ echo "ok 0bad ba1d bad3 4bad4 5bad5bad5" | sed 's/[[:space:]]*[[:alpha:]]*[^[:space:][:alpha:]][^[:space:]]*//g'
ok

答案 1 :(得分:3)

使用awk

s="ok 0bad ba1d bad3 4bad4 5bad5bad5"
awk '{ofs=""; for (i=1; i<=NF; i++) if ($i ~ /^[[:alpha:]]+$/)
         {printf "%s%s", ofs, $i; ofs=OFS} print ""}' <<< "$s"
ok

这个awk命令遍历所有单词,如果单词匹配正则表达式/^[[:alpha:]]+$/,则它会写入标准输出。如果当前字段值不小于(i<NF)?OFS:RS,则OFS是添加NF的捷径,否则会写RS

同时使用grep + tr

s="ok 0bad ba1d bad3 4bad4 5bad5bad5"
r=$(grep -o '[^ ]\+' <<< "$s"|grep '^[[:alpha:]]\+$'|tr '\n' ' ')
echo "$r"
ok

首先grep -o将字符串分成单个单词。第二个grep仅搜索仅包含字母的单词。最后tr\n翻译为空格。

答案 2 :(得分:0)

如果你不担心每个单词之间会丢失不同数量的空格,你可以在Perl中使用这样的东西:

perl -ane 'print join(" ", grep { !/[^[:alpha:]]/ } @F), "\n"

-a开关启用自动拆分模式,该模式将文本拆分为任意数量的空格,并将字段存储在数组@F中。 grep过滤掉包含任何非字母字符的数组元素。生成的数组连接在一个空格中。

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed -r 's/\b([[:alpha:]]+\b ?)|\S+\b ?/\1/g;s/ $//' file

这在替换中使用后向引用来保存所需的字符串。

答案 4 :(得分:-1)

 st="ok 0bad ba1d bad3 4bad4 5bad5bad5"
 for word in $st; 
     do 
     if [[ $word =~  ^[a-zA-Z]+$ ]]; 
         then 
             echo $word; 
      fi; 
 done