我想从文本文件中删除任何包含非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'
答案 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