近期写了一个功能较大的脚本,主要涉及知识点如下,以备后续温故知新。
0:基础知识
//变量声明初始化
i=0
j=2
//更改变量初始值
i=10
j=20
//数值比较
if [[ $i > $j ]];
if (( $i >= $j ));
//数值计算
i=$(($i+1))
j=$(($i+$j))
//逻辑比较
if (( $i >= $j )) && [[ $i == 0 ]];
if [[ ${i} == 1 ]] && [[ ${j} == 1 ]];
//格式化
printf "%04d\n" 2 //0002
//计算列和
]$ awk -F'\t' '{sum+$5};END{print sum}' file
]$ awk -F'\t' '{print $5}' file |awk '{sum+=$1};END{print sum}'
//计算指定行和
awk 'NR=3{for(i=1;i<=NF;i++)sum=sum+$i;}END{print sum}'
NF 代表一行有多少个域 (也就是一行有多少个单词)
$NF代表最后一个域 (也就是最后一个单词)
其他:
${}:避免变量失效, $a 后如果要加字符,直接写的时候 $ 会辨识不到a ,此时要给a加个{ }, ${a}RMB
$[]: 运算, $[1+1]
$(): 使用命令,a=date:命令直接赋给变量是不可以的,a=$[date],此时是可以赋值给a,用波浪号上的另一个小点符号也可以
$(()):运算
[[ ]]:if比较 注意括号左右边须有空格,如if [[ $size == "" ]];
1:获取当时执行的时间点信息
~]$ date //获取 linux 时间戳的命令
Tue Aug 16 16:20:18 CST 2022
//格式化
~]$ date +"%Y-%m-%d"
2022-08-16
~]$ date +"%Y-%m-%d %H:%M:%S"
2022-08-16 16:23:36
//X.sh 内
curDate1="$(date +"%Y-%m-%d")" //注意双引号
current_time=`date +'%Y-%m-%d %H:%M:%S'` //如果担心双引号过多不好理解,可以用反引号和单引号
反引号内的语句,在实际脚本执行时会先执行语句,然后反引号外面的语句再操作语句的结果。
2:逻辑重试,涉及循环
~]$ seq 5 //默认从1开始遍历到指定数字(包括指定数字),返回一个序列
1
2
3
4
5
~]$ seq 3 5 //指定起始数字
3
4
5
for 循环
~]$ for i in $(seq 5); do echo $i; done //in 后面是一个序列,i逐个取值为序列里某个值
1
2
3
4
5
for 循环有一个问题就是,除非遍历完 in 后面的序列,否则无法跳出循环。
~]$ for i in $(seq 5); do $i=10; echo $i; done
bash: 1=10: command not found
1
bash: 2=10: command not found
2
bash: 3=10: command not found
3
bash: 4=10: command not found
4
bash: 5=10: command not found
5
所以重试逻辑还是 while 比较合适。
while 循环
while 循环可以在满足一定的条件下,改变循环条件,从而达到跳出循环的目的。
~]$ i=0; while [ $i -le 3 ]; do i=10; echo $i; done
10
3:shell 多进程有坑,需要控制多进程数量
参见多进程链接,讲解的很好。
tips:
3.1:多进程内逻辑过程最好不要带 cat 之类的语句,容易产生『fork: Cannot allocate memory』的问题,因为进程多了本来就占用内存,如果并发的读大文件会导致某时刻内存竞争被 kill 掉。
待做:
3.1 shell进程数的产生和原理。
3.2 shell 多进程中进程限制数目和循环的进程个数之间的关系探讨。
『shell 注释』:shell 多行注释
『printf 格式字符串』:shell printf 格式字符串
『printf』:Shell printf 命令
『多进程简单 demo』:shell 多进程实现并发
『shell 中的多进程并发』:
shell中的多进程并发
『shell脚本中多线程和控制并发数量』:shell脚本中多线程和控制并发数量(包含同一脚本两个不同的并发数量)