如何在bash中去掉字符串的首尾空格

-- TOC --

在很多编程语言中,直接用trim或者strip就可以轻松实现去掉字符串的首尾空格,但是在bash中,这个事情就需要一点点技巧。

用echo命令(有局限)

$ ABC='   123   '
$ echo ${#ABC}
9
$ V=$(echo $ABC)
$ echo $V ${#V}
123 3

在命令行展开变量的时候,如果不加双引号,通过echo命令输出,就会把参数两边和中间多余的空格去掉,规整参数,但是如果加上双引号,又无法去掉两边的空格:

$ ABC='  1  2  3  '
$ echo ${#ABC}
11
$ V=$(echo $ABC)  # no double quote
$ echo $V -- ${#V}
1 2 3 -- 5
$ V=$(echo "${ABC}")
$ echo "$V" -- ${#V}
  1  2  3 -- 11

V的值显然是错误的!

用grep命令

在echo原样传递的时候,可通过grep命令的-o参数,将匹配的部分取出来:

$ echo '  a1  b2  c3  ' | grep -oE "[^ ].*[^ ]"
a1  b2  c3

但,ASCII中有6个空格字符呀!此时就要使用[:space:]预定义字符集,并且要配合echo的-e参数:

$ echo -e '\n\t  a1  b2  c3  \t\n\t' | grep -oE "[^[:space:]].*[^[:space:]]"
a1  b2  c3

这个方案看起来比较完美了!

用sed命令

还没研究出来...

用awk命令

还没研究出来...

用parameter expansion特性

$ ABC='  a1  b2  c3  '
$ echo ${#ABC}
14
$ V1=${ABC##*( )}
$ echo ${#V1}
12
$ V2=${V1%%*( )}
$ echo ${#V2}
10
$ echo $V2
a1 b2 c3

看着就很复杂的样子...

同样也可以利用[[:space:]]这个预定义的字符集,再封装到一个function里面。

$ cat trim.sh

function trim() {
    # query extglob option and set accordingly
    shopt -q extglob
    if [ $? -eq 1 ]; then
        shopt -s extglob
        local extglob_set=1
    fi
    # transform escape chars
    local v0=$(echo -e "$1")
    # remove all head space
    local v1=${v0##*([[:space:]])}
    # remove all tail space
    local v2=${v1%%*([[:space:]])}
    # recover environment
    if [ ${extglob_set:-0} -eq 1 ]; then
        shopt -u extglob
    fi
    # output to stdout
    echo "$v2"
}


A='\n\t\v  1  2  3  \n\t\v'
A=$(trim "$A")  # must be doubel quote
echo "$A"
$ bash trim.sh
1  2  3

必须要打开extglob这个option才可以!

用Python实现

不是写python脚本,那个太复杂了,直接在命令行用Python:

$ ABC='\v\t\v\n 2   3  \t\t\v\n  '
$ echo "a='$ABC'.strip();print(a,'|',len(a))" | python3 - 
2   3 | 5
$ B=$(echo "print('$ABC'.strip())" | python3 -)
$ echo "$B" '|' ${#B}
2   3 | 5

双引号内的单引号,就是单纯的单引号!

Python方案跟grep方案比较,发现escape chars在两种编程环境下的差异!

另一种Python方案:

$ echo -e '\n\n\t 2 3  5 \v\v\t' | xargs -I{} python3 -c "print('{}'.strip())"
2 3  5
$ echo -e '\n\n\t 2 3  5 \v\v\t' | xargs -I{} python3 -c 'print("{}".strip())'
2 3  5

用C语言实现

自己写个C语言的程序,放到/usr/bin目录里面去。

本文链接:https://cs.pynote.net/sf/linux/shell/202202072/

-- EOF --

-- MORE --