shell小技巧

shell小技巧 #

随着各种开源软件,各种编排工具的普及,大规模写shell的机会越来越少,但是,“只言片语”的shell还是随时需要的。 shell对于运维和开发来说,就是瑞士军刀,关键时刻,能简化工作,节省时间。 长时间不用就容易忘记,俗话说:“好记性不如烂笔头”,特此,开此篇记录一下shell的常用片段。

shell的核心在于文本的处理

1. for循环时字符串的分割引发的分隔符思考 #

比如下面的字符串,使用for遍历:

#!/bin/bash
t='l11 l12
l21 l22 l23'

for i in $t
do
    echo start - $i
done

结果:

# bash a.sh
start - l11
start - l12
start - l21
start - l22
start - l23

in后就相当于有一次隐式变换,将字符串分割,分隔符自动选择了\n ,但有时候并非我想要的,那该怎么办?

使用IFS控制分隔符

#!/bin/bash
t='l11 l12
l21 l22 l23'

IFS=$'\n'
for i in $t
do
    echo start - $i
done

结果:

# bash a.sh
start - l11 l12
start - l21 l22 l23

其中$'\n'是有说法的,如下:

Words of the form $‘string’ are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.

$ echo 'foo\n'
foo\n
$ echo $'foo\n'
foo

除了上述隐式分割,我们也可以使用array来控制遍历单元,想要打印每一个元素:

t='l11 l12
l21 l22 l23'
IFS=$'\n' x=(${t//$'\n'/ })

unset IFS
for i in ${x[@]}
do
    echo start - $i
done

结果:

# bash a.sh
start - l11
start - l12
start - l21
start - l22
start - l23

${t//$'\n'/ }使用变量替换,将\n替换为 空格,然后再遍历

使用数组读取:

#!/bin/bash
t='l11 l12
l21 l22 l23'
IFS=$'\n' readarray -t x <<<"$t"

echo ${#x[@]}

IFS=$'\n'
for i in ${x[@]}
do
    echo start - $i
done

结果:

# bash a.sh
2
start - l11 l12
start - l21 l22 l23