shell数组与OneLiner

一些小的知识点

tips:

在perl中,有一种可以直接在命令行使用的program被成为one-liner,虽然没写perl,但是记一下shell中使用的one-liner吧

1
2
3
4
5
6
--- ~ » echo {1..10..2}
1 3 5 7 9
--- ~ » sum=0;for i in {1..100};do sum=$((sum+=i));done;echo $sum
5050
--- ~ » awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
5050

通过awk与shell的for循环对比发现,awk的效率比shell高很多!在计算一亿的和的时候,awk用了7s,而shell则是很慢,等了几十秒也没出结果。

hash

可以称为hash/map/dict,总之就是一个名字而已,代表的是二维数据。之前写shell的时候很奇怪shell为什么没有hash这种数据结构呢?我了解到的知识就是一维的数组而已,使用起来还是有些不方便。

认真的说,其实不是没有,而是我没有学过。但是即使没有学过,用已经了解到的知识其实也可以写的,只是,学东西学的不好吧,没理解到hash的真谛。hash二维i数据,是一维数据的扩展,可以理解为一种映射,更深层次就是说数据间存在某种联系。所以用老的知识也是可以写出hash的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--- ~ » user=xiaoxiao
--- ~ » age=20
--- ~ » score=100
--- ~ » list=($user $age $score)
--- ~ » for i in ${list[@]};echo $i
xiaoxiao
20
100

--- ~ » echo ${list[1]}
xiaoxiao
--- ~ » echo ${list[2]}
20
--- ~ » echo ${list[3]}
100

--- ~ » echo $list
xiaoxiao 20 100

上面这个例子,虽然看上去也并不是hash,因为取数据也只是用到了索引,但是至少存在了引用,建立了联系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ARRAY=( "cow:moo"
"dinosaur:roar"
"bird:chirp"
"bash:rock" )

for animal in "${ARRAY[@]}" ; do
KEY="${animal%%:*}"
VALUE="${animal##*:}"
printf "%s likes to %s.\n" "$KEY" "$VALUE"
done

cow likes to moo.
dinosaur likes to roar.
bird likes to chirp.
bash likes to rock.

上面这个例子,是别人写的,用简单的字符串也建立起了数据间的联系。

下面要写shell中专门的hash了,在bash中使用。zsh中有些不同(获取key时报错)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# create associate array
declare -A user
user=([name]=xiaoxiao [age]=20 [score]=100)
# simplify
declare -A user=([name]=xiaoxiao [age]=20 [score]=100)

# add value
user[like]=apple

# get all keys
[narcissus@archlinux ~]$ echo ${!user[@]}
score age like name

# get all values
[narcissus@archlinux ~]$ echo ${user[@]}
100 20 apple xiaoxiao

# get specified value
[narcissus@archlinux ~]$ echo ${user[name]}
xiaoxiao

# get length
[narcissus@archlinux ~]$ echo ${#user[@]}
4

declare还具有大小写转换的功能

1
2
3
4
5
6
--- ~ » declare -u name=`whoami`
--- ~ » echo $name
NARCISSUS
--- ~ » declare -l name
--- ~ » echo $name
narcissus

下面是日常的吐槽:加了几个群,看见群里的小伙伴说话都特别搞笑,什么一个星期学完python啊,就好像看到了我自己一样,我说我会六种语言,c,python,java,shell,perl,haskell。其实这都是假的,只不过我学过而已,而且都只是会点皮毛,而且c语言那还是大二的选修课,现在连个helloworld都不会写,java更是写都不想写,haskell嘛,学都没学懂。其它的勉强会用而已。就连我写的最多的shell,我发现连个hash都不会。所以很多时候,我们还是太轻浮了,学习不应该以这种态度的。就好比是这样一个变量的简单定义,可能有的人看一眼就说会了,不就是赋值吗,其实在理解的多一点还涉及到内存的分配,再多理解一点呢,可能就会通过一维数组去建立二维数据,如果了解的多一点,我们会发现就是这么简单的一个概念,却是perl玩的出神入化的核心。所以知识呢,永远没有尽头,不同的人有不同的理解程度,不要轻浮的觉得自己会多少东西了。当然了知识的广度也是一个很重要的方面,比如说一个paste命令解决了困扰好久的问题。

为什么会有这么多无聊的想法呢,还不是一个人闲的,其实我只是想说linux我不能说我懂多少,因为一个awk的man手册我都没有完整的看一遍,哪有资格说懂linux了呢?