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

Linux sed:删除包含字符类的整个单词,linux,bash,command-line,awk,sed,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' 使用awk: s="ok 0bad ba1d bad3 4bad4 5bad5bad5" awk '{ofs=""; for (i=1; i<=

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

使用
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

首先
grep-o
将字符串拆分为单个单词。第二个grep只搜索带有字母的单词。最后,
tr
\n
转换为空格。

使用
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
 st="ok 0bad ba1d bad3 4bad4 5bad5bad5"
 for word in $st; 
     do 
     if [[ $word =~  ^[a-zA-Z]+$ ]]; 
         then 
             echo $word; 
      fi; 
 done

首先
grep-o
将字符串拆分为单个单词。第二个grep只搜索带有字母的单词。最后,
tr
\n
转换为空格。

如果您不担心在每个单词之间丢失不同数量的空格,您可以在Perl中使用如下内容:

 st="ok 0bad ba1d bad3 4bad4 5bad5bad5"
 for word in $st; 
     do 
     if [[ $word =~  ^[a-zA-Z]+$ ]]; 
         then 
             echo $word; 
      fi; 
 done
perl -ane 'print join(" ", grep { !/[^[:alpha:]]/ } @F), "\n"

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

如果您不担心在每个单词之间丢失不同数量的空格,您可以在Perl中使用如下内容:

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

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

以下sed命令执行此操作:

sed 's/[[:space:]]*[[:alpha:]]*[^[:space:][:alpha:]][^[:space:]]*//g'
它删除至少包含一个非字母字符的所有单词。最好使用POSIX字符类,如<代码> [Alph::] /Cord>,因为例如,他们不会认为法语名字“弗兰Cou-OIS”是错误的(即包含非字母字符)。

解释 我们删除所有模式,从任意数量的空格开始,后跟任意(可能为零)数量的字母字符,后跟至少一个非空格和非字母字符,然后全局移动到单词的末尾(即,直到下一个空格)。请注意,您可能希望将
[:space://code>替换为
[:blank://code>,有关这两个POSIX类之间差异的详细说明,请参阅

测验
以下sed命令执行此任务:

sed 's/[[:space:]]*[[:alpha:]]*[^[:space:][:alpha:]][^[:space:]]*//g'
它删除至少包含一个非字母字符的所有单词。最好使用POSIX字符类,如<代码> [Alph::] /Cord>,因为例如,他们不会认为法语名字“弗兰Cou-OIS”是错误的(即包含非字母字符)。

解释 我们删除所有模式,从任意数量的空格开始,后跟任意(可能为零)数量的字母字符,后跟至少一个非空格和非字母字符,然后全局移动到单词的末尾(即,直到下一个空格)。请注意,您可能希望将
[:space://code>替换为
[:blank://code>,有关这两个POSIX类之间差异的详细说明,请参阅

测验 这可能适用于您(GNU-sed):

这将在alternation中使用back引用来保存所需的字符串。

这可能适用于您(GNU-sed):


这将在alternation中使用back引用来保存所需的字符串。

要删除的是非字母还是数字?你的尝试有什么问题?都是非字母的,不仅仅是数字。它产生了一个错误的答案。您要删除的是非字母,还是数字?你的尝试有什么问题?都是非字母的,不仅仅是数字。它产生了一个错误的答案。@Dimid:我在我的答案中添加了解释。我重复下面写的评论:请使用
[[:alpha:]
而不是buggy
[a-zA-Z]
,因为如果您在
s
中用“Öcalan”替换您的“ok”,例如,您的脚本将输出一个空字符串:(@Jotne-在某些awk(例如OSX awk)中,
print
将根据三元表达式中的条件在
print()时导致语法错误)
总是会成功的。我不确定是否有其他情况下,未括号化的三元表达式会失败,也不知道仅仅在表达式的条件部分加括号是否足以解决这一问题。我个人觉得用括号化整个表达式更容易阅读,而且我知道它在所有情况下都有效tuations所以我就这么做了。我实际上在OSX上工作,并使用awk的默认OSX版本在awk上面进行了测试。但是,是的,为了更好的兼容性,似乎最好使用
(iYes),正如我提到的,您的解决方案是添加一个尾随空白字符,而不提供换行符。您需要
awk'{ofs=“”;用于(i=1;i@Dimid:我在回答中添加了解释。我重复下面的评论:请使用
[[:alpha:]
而不是buggy
[a-zA-Z]
,因为如果您在
s
中用“Öcalan”替换您的“ok”,例如,您的脚本将输出一个空字符串。:(@Jotne-在某些awk中(例如OSX awk)
print
print()时,根据三元表达式中的条件,将导致语法错误
总是会成功的。我不确定是否有其他情况下,未括号化的三元表达式会失败,也不知道仅仅在表达式的条件部分加括号是否足以解决这一问题。我个人觉得用括号化整个表达式更容易阅读,而且我知道它在所有情况下都有效tuations所以我就这么做了。我实际上在OSX上工作,并使用awk的默认OSX版本在awk上面进行了测试。但是,是的,为了更好的兼容性,似乎最好使用
(iYes),正如我提到的,您的解决方案是添加一个尾随空白字符,而不提供换行符。您需要
awk'{ofs=“”;用于(i=1;i+1,我自己也在尝试沿着这些思路解决一些问题*