如何从脚本中的字符串中删除非字母?

时间:2016-06-30 20:11:58

标签: string bash shell

我有:

something='sl89wS Gjf-_32b'

我想回来:

slwsgjfb

如何让它只返回字母,然后将所有内容都小写?

2 个答案:

答案 0 :(得分:3)

您可以使用参数扩展:

${something//[^[:alpha:]]/}

此处变量[^[:alpha:]]的所有非字母字符(something)将被替换为无,即将被省略。

示例:

$ str='sl89wS Gjf-_32b'
$ echo "${str//[^[:alpha:]]/}"
slwSGjfb

答案 1 :(得分:1)

基本的想法是替换不是字母的所有内容:

[^a-Z]

什么都没有:

$ s='sl8zZ9wS Gjf-_32b'
$ echo "${s//[^a-Z]}"
slzZwSGjfb

适用于LC_ALL=en_US.UTF-8。但是,如果使用的字符包含重音字形(假设不需要带重音的字形),那么这个想法就会失败:

$ s='sl8zZ9wS Gjf-_3éëì2b'
$ echo "${s//[^a-Z]}"
slzZwSGjféëìb

或整理顺序更改:

$ LC_COLLATE=C
$ echo "${s//[^a-z]}"
slzwjfb                       ### Missing upper chars.

在这些情况下,需要更可靠的字符列表:

$ s='sl8zZ9wS Gjf-_3éëì2b'
$ echo "${s//[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]}"
slzZwSGjfb

最终可靠的命令行应该是:

$ s="$( LC_ALL=C eval printf '%s' "${s//[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]}" )"

或更短(如果整理顺序是ASCII字节值):

$ s="$( LC_ALL=C eval printf '%s' "${s//[^a-zA-Z]}" )"

将转换添加到大写字符:

$ printf '%s\n' "${s^^}"
SLZZWSGJFB

当然,所有人都受到打击。