一些Shell脚本
一、for循环
1.1 遍历数组
ARR=(aaa bbb ccc)
for obj in ${ARR[*]}
do
echo ${obj}
done
1.2 普通for循环
-gt
是大于的意思
continue
跳出当前循环,如果是 break
则终止循环
注意: 缩进和空格
for((f=1;f<=10;f++))
do
if [ $f -gt 5 ]
then
continue
fi
echo "$f"
done
1.3 切换用户,退出用户
root用户登录,在for循环中切换用户,然后退出,下一次循环继续切换用户,使用下面的EOF
,这样exit
就不会退出shell程序了
ARR=(aaa bbb ccc)
for obj in ${ARR[*]}
do
echo ${obj}
su - test <<EOF
pwd
exit
EOF
done
注意: 第二个EOF不能有缩进,不然会有问题
二、awk相关
2.1 结合pe-ef,打印指定列
ps -ef | grep java | awk '{print $1,$2,$3,$4,$5,$6,$7}'
2.2 使用printf格式化结果
%-15s:
string长度不足15,按空格补齐
ps -ef | grep java | awk '{printf "%-15s %-15s %-15s %-15s %-15s %-15s %-15s\n" ,$1,$2,$3,$4,$5,$6,$7}'
%-8.2f:
以小数的形式输出,保留两位小数,整数+小数点+小数+空格的长度为8
awk '{printf "%-8.2f %-8.2f %-8.2f %-8.2f %-8.2f\n",$1,$2,$3,$4,$5}' test.txt
2.3 过滤空行
//
中间的代表正则
awk '!/^$/' test.txt
2.4 去空行,打印行号,使用循环加判断,格式化输出
NF
代表每一行的总列数,默认按照空格分开
NR
代表行
期望:去除空行,每一行的前三列
awk '!/^$/' test.txt | awk '{printf "%-2s ",NR}{for(f=1;f<=NF;f+=1){if(f<=3){printf "%-15s",$f}}}{printf "\n"}'
2.5 if条件判断
期望:找出每行中包含 Zhang 的列
awk '{for(f=1;f<=NF;f+=1){if($f~/Zhang/){printf "%-12s",$f}}}{printf "\n"}' test.txt
三、使用变量获取执行结果
使用``可以
获取脚本执行的结果,注意AAA=`的中间没有空格
AAA=`ps -ef | grep java`
echo ${AAA}
四、使用正则对脚本执行结果的每行进行判断
pattern="HeartBeat"
# tail -n 5 /home/test/log/log_20150205.log 也可以是 ps -ef | grep java
tail -n 5 /home/test/log/log_20150205.log | while read line
do
if [[ $line =~ $pattern ]]
then
echo "Match"
else
echo "No match"
fi
echo $line
done
五、管道符和while一起使用导致循环外变量值的问题
开始错误的情况:
lineCount=0
cat data.txt | while read line
do
lineCount=$(($lineCount+1))
echo "循环内lineCount:${lineCount}"
done
echo "循环外lineCount:${lineCount}"
修改之后:
lineCount=0
while read line
do
lineCount=$(($lineCount+1))
echo "循环内lineCount:${lineCount}"
done < data.txt
echo "循环外lineCount:${lineCount}"
或者:
lineCount=0
cat data.txt > /tmp/$$.list
while read line
do
lineCount=$(($lineCount+1))
echo "循环内lineCount:${lineCount}"
done < /tmp/$$.list
echo "循环外lineCount:${lineCount}"
rm -rf /tmp/$$.list
/tmp/$$.list
是当前执行的脚本PID对应的文件,当作临时文件使用
六、动态进度条demo
#!/bin/bash
i=0
j='#'
k=('|' '\' '-' '/')
l=0
while [ $i -le 25 ]
do
printf "progress:[%-25s][%d%%][%c]\r" $j $(($i*4)) ${k[$l]}
j+='#'
let i++
let l=i%4
sleep 0.1
done
printf "\n"
七、sed相关
7.1 匹配含有某些字符的行,并替换掉整行
举例:因为不知道port 后面是6666,所以得替换port整行,不管是啥,都替换成8888,而且port前面的空格需要保留
# 原文本
spring
server
port: 6666
# 替换后的文本
spring
server
port: 8888
代码:
# 获取含有port的行号,注意 aaa=`中间不能有空格
# ``是将执行的结果赋值给变量aaa
aaa=`sed -n -e '/port/=' sedtest.txt`
echo $aaa
# 删除指定行,注意 要用双引号,不然不能引用变量
sed -i "$aaa d" ./sedtest.txt
# 在指定行之前添加指定字符串,\后面有几个空格就代表port前面有几个空格
# 注意,如果删除的是最后一行,则添加行无效,需要在(aaa-1)行之后添加行
sed -i "$aaa i \ port: 7777" ./sedtest.txt