bash 实用技巧

一..将文件的内容赋给一个变量:

  file=$(cat filelist)

       file=$(< file)

NOTE:后者性能比前者好

二..bash 分组匹配:

HOSTNAME='mysql-10=='

[root@node2 ~]# [[ $HOSTNAME =~ -([0-9]+)(.*) ]];VAR=${BASH_REMATCH[0]};echo $VAR
-10==
[root@node2 ~]# [[ $HOSTNAME =~ -([0-9]+)(.*) ]];VAR=${BASH_REMATCH[1]};echo $VAR
10
[root@node2 ~]# [[ $HOSTNAME =~ -([0-9]+)(.*) ]];VAR=${BASH_REMATCH[2]};echo $VAR
==

三..命令替换:

1.$(ls)

2.`ls`

四.新开一个子shell执行命令:

(umask 000;mkdir hello;mkdir word)

创建了两个目录,权限都为777

五.set

set -x 以debug模式执行shell,显示执行过程

set -e 如果某一条shell出错就不再往后继续执行

正则表达式:

[[space:]]          #空白字符

[[:digit:]]            #数字

[[:alnum;]]         #数字和字母

[[:punct:]]          #标点符号

[[:lower:]]          #小写字母

[[:upper:]]         #大写字母

[[:alpha:]]         #大小写字母

.                      #匹配单个字符

*                     #匹配前面字符任意次

.*                     #匹配任意长度字符,也包含空行

?                   #匹配前面字符一次或零次

{m,n}           #匹配前面字符至少M次,最多n次

(ab)             #分组匹配,主要用于搭配后项引用,前面匹配到什么,后面就引用什么(eg:grep "(l..e).*1$" test    #匹配以括号中匹配到的内容结尾的行)

位置锁定:

  ^            #行首(如果出现在'[ ]'中,则表示排除,eg grep '[^1-2]' test,表示排除除了1和2的行)

       $            #行尾

      ^$           #空行

      <           #词首

      >           #词尾

grep参数:
-i          #忽略大小写

-n        #显示行号

-c        #统计符合条件的行

-v        #排除符合条件的行

-An     #打印符合条件行及下面的n行

-Bn     #打印符合条件行及上面的n行

-Cn     #打印符合条件的行及上下n行

egrep:

+           #匹配前面字符至少一次

?           #匹配前面字符一次或零次

{m,n}  #匹配前面字符至少m次,最多n次

(a|b) #匹配a或b

sed:

参数:

-n 静默模式,不再显示模式空间的内容

-i  直接应用在文件中生效,如果不加-i,只是输出到屏幕而不应用到文件

-r 使用扩展正则表达式

-f 保存至文件执行

sed '/hello/a est' test   #在匹配到内容的下一行追加指定内容

sed 's/hello/&test/' test #在匹配到的内容后追加新内容

wd 's/hello/test&/' test  #在匹配到的内容前追加新内容

sed '1i est' passwd      #在第一行前面添加test

sed '1a est' passwd     #在第一行后面添加test

sed -n '1'p passwd       #打印第一行

sed '1w test' passwd    #将第一行内容写到test中

sed '1r test' passwd     #将test中的内容添加到第一行后面

sed 's/test/TEST/'g test     #将test中的test换位大写的TEST

sed -i '/string/,+3d' .         #删除匹配到的行及其下面的三行

sed -r -i 's/(version: [0-9].[0-9].)([0-9]+)/1a/' Chart.yaml    # sed 分组匹配

sed默认每次只替换一行中第一个命中的,如果要替换每行的所有匹配到的用[/g]:

sed -i 's/a/e/g' abcd.txt

如果只想替换每行第一次出现的,可以去掉[/g]:
sed -i 's/e/a/' abcd.txt

sed默认会匹配全文,也可以让他匹配指定次数就退出,可以用【0,/待替换内容/s/待替换内容/替换内容/】:
sed -i '0,/a/s/a/e/' abcd.txt
在第一次匹配的行做全部替换:
sed -i '0,/a/s/a/e/g' abcd.txt 
如果每次想替换两行怎么办?那就把0,/改为1,只替换两行,替换两行中所有匹配到的/
sed -i '1,/a/s/a/e/g' abcd.txt 
每次替换两行,每次替换每行中第一次匹配到的:
sed -i '1,/a/s/a/e/' abcd.txt

sed -i '0,/a/s/a/e/' abcd.txt  #实现每次只替换一个a:使用【0,/待替换内容/s/待替换内容/替换内容/】

(参考博客:https://www.cnblogs.com/wjlv/p/10772888.html

NOTE:

1.sed中/可以用@或者#代替

2.sed中如果要引用系统的环境变量,可以用单引号,如:sed '/`test`/d' test

3.从shell向sed传值: echo $NAME | sed "s/go/$REP/g" 注意需要使用双引号

eg:

sed 's#test#TEST#'g test

sed 's@test@TEST@'g test

替换字符位置:

#cat test

three one

sed 's/(three)(.*)(one)/321/' test

res:  

one three

##### bash 

: #占位符号

echo $((2**3))    #数值运算

((a=10+10));echo $a    #数值运算

(pwd;ls) 与{pwd;ls} 的区别,{}  和()类似,也是将多个命令组合在一起。它们之间的区别是,()是在产生的子shell下执行,而{}是在当前的shell下执行

 #####

until:给while 用法一致,不过while 是为真是循环,而until是条件为假时才执行

##########

shift:用于给脚本传多个关键字参数

while [[ $# -gt 0 ]]
do
#获取第一个参数
key="$1"

case $key in
#主节点IP
--master-address)
export MASTER_ADDRESS=$2
#向左移动位置一个参数位置
shift
;;
#获取docker存储路径
--docker-graph)
export DOCKER_GRAPH=$2
#向左移动位置一个参数位置
shift
;;
#获取docker加速器地址
--docker-mirrors)
export DOCKER_MIRRORS=$2
#向左移动位置一个参数位置
shift
;;
*)
# unknown option
echo "unkonw option [$key]"
;;
esac
shift
done

 运行方式:kubeadm.sh --node-type master --master-address 10.40.72.51

##########

shell 数组:

ARR=(a b c)

#遍历数组:

for NUM in ${ARR[*]}
do
  echo $NUM
done
 
#判断字符是否在数组中

if echo "${ARR[@]}" | grep -w "a" &>/dev/null; then     
continue
fi

#向数组添加新成员:

ARR[1]="item_1"
ARR[2]="item_2"
 
#取出一个成员:
echo ${ARR[2]}

###echo 后面的内容加引号与不加引号的区别:

echo *    #显示当前路径

echo "*"  #显示*

linux ps:

ps1:修改默认提示符

ps2:修改分行符号  ##一个非常长的命令可以通过在末尾加“”使其分行显示。多行命令的默认提示符是“>”。 我们可以通过修改PS2 ,将提示符修改为"continue->" 

ps3:修改PS3——Shell脚本中使用select时的提示符

ps4:修改 set -x 脚本调试执行时前面显示的字符

参考连接:https://blog.csdn.net/rainharder/article/details/54573021

将二进制文件嵌入到shell脚本:

有时候我们的项目可以有二进制文件,有图片,有说明文档等,这个时候发布项目可以打成一个包或者一个文件夹有组织的存放这些文件,很方便,但有时候也可以把他们放入到一个shell脚本中,这个对用户也非常友好,只需要运行一个shell脚本就ok:

1.先写一个脚本:test.sh

#!/bin/bash
sed '1,5/d' $0 > test     
echo "ok"
chmod +x test
exit 0
END  

2.把二进制内容追加到test.sh 后面: cat 二进制文件 >> test.sh

嵌入后的shell:

#!/bin/bash
sed '1,5/d' $0 > test   #将第一行至分隔符行删除,将后面二进制分离出来         
echo "ok"
chmod +x test
exit 0
END    ###分隔符
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^B^@>^@^A^@^@^@`ÈF^@^@^@^@^@@^@^@^@^@^@^@^@p^B^@^@^@^@^@^@^@^@^@^@@^@8^@

原理:shell 运行时将对应的二进制分离出来然后执行。

生产环境shell字符处理实例:

#!/bin/bash
dir="/home/feixiang.du/charts"

all_project=`ls -l /home/feixiang.du/charts | sed '1,2d' | awk '{print $NF}'`

for i in ${all_project}
do
  #跳过指定charts
  ignore_chart=(istio istio-cni alert-hook istio-init nginx-demo auth demo phpserver-helloworld dove-override-svc-bj2 chartmuseum chartmuseum-external dove-override-svc-bj3 prometheus-operator pub-entry-nginx dove-override-svc-pub configmap-filebeat.yaml dove-server pub-entry-nginx-stream push-charts.sh rpcmon filebeat tech-sdkwrapper k8swan kubeapps log-clean log-collect inner-ingress crm-center-internal-api)

if echo "${ignore_chart[@]}" | grep -w "$i" &>/dev/null; then
    continue
fi

   if ! [ -f ${dir}/${i}/Chart.yaml ]
   then
       continue
   fi
   #处理charts版本
   current_ver=`cat "${dir}/${i}/Chart.yaml" | grep "version" | awk -F. '{print $NF}'`
   new_version=$(($current_ver+1))
   sed -r -i 's/(version: [0-9].[0-9].)([0-9]+)/1'$new_version'/' ${dir}/${i}/Chart.yaml
   #调整successThreshold = 2
   sed -r -i '0,/successThreshold/s/(successThreshold: )([0-9])/12/'  ${dir}/${i}/templates/deployment.yaml
   #增加affinity

   if ! [ -f ${dir}/${i}/templates/deployment.yaml ]
   then
       continue
   fi
   ##删除charts中已存在的affinity行
   sed -i '/affinity/,+3d' ${dir}/${i}/templates/deployment.yaml

   num=`cat -n ${dir}/${i}/templates/deployment.yaml | grep "Values.tolerations" |awk '{print $1}'`
   insert_num=$(($num-1))
   sed -r -i ''$insert_num'r affinity' ${dir}/${i}/templates/deployment.yaml

   chartname=$i
   export chartname
   envsubst < values.tml > values
   sed -i '/affinity: {}/d' ${dir}/${i}/values.yaml
   sed -r -i '$r values' ${dir}/${i}/values.yaml
done
View Code
原文地址:https://www.cnblogs.com/dufeixiang/p/10808507.html