锋利的Bash(2)

数组

参考:

  1. 初级一点的bash数组教程
  2. 高级一点的15 个 Bash Array 数组教程

我这里就总结几点我觉得主要注意的地方:

  1. 数组特点
    数组下标从0开始,支持负数索引,使用[*]或[@]将数组转化为字符串列表(这两个是存在区别的,后面说),否则只是通过$符号只能拿到下标为0的元素。计算长度时,被删除(unset)的元素不计入长度
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    declare -a array
    array[0]='a'
    array[1]='bb'
    array[2]='ccc'
    echo ${#array[*]} : ${array[*]}
    echo first element : $array
    unset array[0]
    echo ${#array[*]} : ${array[*]}
    echo first element : $array
    echo last element : ${array[-1]}
  1. 数组和字符串的类似之处
    都支持切片,因为数组可以通过@符号转换为字符串,一次可以使用字符串的替换(类似于sed的语法)功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 切出从下标2开始的长度为2的片
    s="i am so hot hoot"
    a=(i am so hot hoot)
    echo ${s:2:2} # am
    echo ${a[@]:2:2} # so hot
    # 替换
    echo ${s/hot/cold}
    aa=${a[*]/hot/cold}
    echo $aa # 会输出全部内容,也就是说aa是字符串了
    # 删除
    echo ${s/ho*t/}
  2. 数组和字符串的长度计算方式

    1
    2
    3
    4
    s="a b c"
    a=("aa" "bb" "cc")
    echo ${#s} # output:5
    echo ${#a[@]} # output:3
  3. 关联数组
    Bash支持关联数组,它可以使用字符串作为数组索引,有时候采用字符串索引更容易理解。

    1
    assArray=([lucy]=beijing [yoona]=shanghai)

参考shell数组与关联数组

函数

bash中用$使用一个字符串变量的时候就直接当做吧字符串的内容替换到变量所在位置就行。并且可以使用forin直接遍历被空格分割的字符串内容,这个是很容易理解的。
但是结合数组的时候就会有一点混乱。

  1. 数组作为参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    bb=(a1 a2 a4 a6)
    cc="a1 a2 a3"
    function f
    {
    echo 参数个数: $#
    echo 第一个参数: $1
    echo 第二个参数: $2
    echo 所有参数列表: $*
    echo
    }
    f $bb
    f ${bb[@]}
    f ${bb[*]}
    f "${bb[@]}"
    f "${bb[*]}" # 这个方式可以吧数组作为一个整体传进函数
    f $cc
    f "$cc"
    f "$cc[*]"
  2. 返回值
    第一、return是返回值,但是只能用#?在下一条命令捕获,不能直接传递给自定义变量。第二、return作为返回状态值只能是整数。第三、某些版本的bash脚本中不支持return,只能用exit退出。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function f
    {
    echo "stdout value"
    return 1
    }
    a=`f`
    b=$?
    echo $a
    echo $b

解释:双引号包含时,”$*”的参数被当做一个整体,而”$@”还是遍历每一个参数

字符串

涉及到字符串或者说文本的处理是我认为bash中最复杂的地方。仅仅是通过${str}的处理就可以完成绝大多数的任务,这个部分也只介绍这种相关方法。

参考:
shell字符串操作详解
Shell脚本8种字符串截取方法总结
shell中的${},##和%%的使用

  1. 基本操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    a=asd123qwe456asd123qwe456
    # 切片
    # 下标从0开始,支持负数索引,-1表示最后一个字符
    echo ${a:1} # sd123qwe456asd123qwe456
    echo ${a:1:3} # sd1
    echo ${a:0-6:3} # 从-6开始往右数3个:qwe,注意0是必须的
    echo ${var:(-6):3} # 或者使用括号
    # 删除
    # #/##/%/%%分别表示在串头、串尾删除最短、最长子串
    # 星号匹配任意字符、支持正则
    echo ${a#asd[0-9]}
    echo ${a##*asd}
    echo ${a%%456*}
    #替换
    echo ${a/#asd/ASD} # 替换前缀
    echo ${a/%456/123} # 替换后缀
    echo ${a/asd/ASD} # 替换第一个
    echo ${a//asd/ASD} # 全部替换
  2. expr
    可以使用info expr查看文档。支持字符串操作和数值计算。

    1
    2
    3
    4
    5
    6
    7
    expr index 12345 234 # 子串位置,下标从1开始
    expr match 12345asd [0-9]* # 从头匹配最大长度
    expr length 12345 # 计算长度
    expr asd123qwe456 : asd[0-9]* # 6:从头匹配的正则长度
    expr asd123qwe456 : '\(asd[0-9]*\)' # 从头匹配到的字串,要加上引号并把想输出的分组用\(\)括起来,为啥加引号不知道。
    expr substr abcde 2 3 # bcd,下标从1开始
    expr index + length g # 加号对关键字进行转义

echo

-n参数表示不在结尾加换行符
-e参数表示对转义字符进行解释,否则不解释,接受的转移字符有:

  • \r 光标移至行首,但不换行
  • \t 插入tab
  • \f 换行但光标仍旧停留在原来的位置
  • \b 删除前一个字符
1
2
3
4
5
echo -n "123" > result
echo -e "\r456\f123" >> result
# 控制显示颜色:echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"
# 字颜色:30—–37,字背景颜色范围:40—–47
echo -e "\033[41;37m 红底白字 \033[0m"

cut

-d:分隔符
-c:按字符分割
-f:第几个字段(从1开始, 支持多个字段)
--complement:输出未被选中的字段
--out-delimiter=:指定输出分隔符

1
2
3
echo "1;2;33;444;55;6" | cut -d \; -f 2,4 # output:2;444,还会用原分隔符进行分割
echo "1;2;33;444;55;6" | cut -c 2,4 # output:;;
echo "1;2;33;444;55;6" | cut --complement -d \; -f 2,4

paste按列合并文件

-d:指定分隔符

1
2
3
echo -e "1\n2\n3" > 1
echo -e "4\n5\n6" > 2
paste 1 2

本站总访问量