linux探路-shell scripts

一直相对shell脚本进行系统性学习,由于时间的原因,每次都是看一点,过一段时间又忘了,这次狠下心做一次shell script的学习和分享,和大家一起掌握好shell,下面先大体描述下技术层面的shell,后面主要就是练习。

首先什么是shell script呢?它是利用shell的功能所写出来的一个程序,这个程序是使用纯文本文件,将一些shell提供的命令写在里面,再搭配正则表达式、管线、数据流导向等功能,以达到我们想要处理的目的。

那script的执行方式有哪些,它们之间又有什么区别?一共三种分别是./script、sh script以及source script。

在执行./script、sh script时,该脚本都会使用一个子程序(新的bash)环境来执行脚本内的命令,当子程序完成后,在子程序内的各种变量或动作将会结束而不会传回父程序中,即你在子程序中声明的变量,在父程序中是使用不了的。

而在执行source script时,脚本是在父进程中执行的,所有脚本执行完,其中的变量还是能继续使用。

下面主要就是实战:

一、善用判断:

1、test:

2、利用判断符号[]:[ "${name}" == "name" -o  "${name}" == "Name" ]

数字的比较: 

-eq 相等(equal) 

-ne 不等(not equal) 

-gt 大于(greater than) 

-lt 小于(less than) 

-ge 大于等于 (greater than or equal) 

-le 小于等于 (less than or equal)

字符串的比较: 

$str1 = $str2 ] 等于 

$str1 != $str2 ] 不等于 

[ -z $str ] 空字符串返回true 

[ -n $str ] 或者 [ $str ] 非空字符串返回true

a、在[]中的每一个组件都需要有空格键来分隔

b、在[]里的所有变量最好都以双引号括号起来

c、在[]里的所有常量最好都以单/双引号括号起来---这里建议一样使用双引号

3、默认变量:$0、$1等

a、$#:代表参数的个数

b、$@:将所有变量用引号括起来,即'opt1 opt2 opt3 opt4'

对于$str代表什么意思可以参考:https://www.cnblogs.com/kaituorensheng/p/4002697.html

4、shift造成变量偏移:

当script中执行过shift后,$@:将所有变量用引号括起来,即'opt2 opt3 opt4' 

5、if....then:

句式:

if [ 条件一 ];then

elif [ 条件二 ];then

else

fi

&&代表AND

||代表or

[ "${yn}" == "y" or "${yn}" == "Y" ] 和 [ "${yn}" == "y" ] || [ "${yn}" == "Y" ]

6、利用case......esac:

7、循环

a、while [ 条件 ]

do

         pass

done

b、for var in con1 con2 con3

      do

          pass

      done

c、for (( 初始值;限制值;执行步骤))

      do

            pass

      done

二、xargs、awk和sed

1、xargs:

之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令,然后将管道中的输出,每一行执行以下后面的命令,如果后面没有命令,默认echo

下面主要了解下相关参数:

-d:默认情况下xargs将其标准输入中的内容以空白(包括空格、Tab、回车换行等)分割成多个之后当作命令行参数传递给其后面的命令,并运行之,我们可以使用 -d 命令指定分隔符

例:echo '11@22@33' | xargs -d '@' echo 
                  输出: 11 22 33

-n:该选项表示将xargs生成的命令行参数,每次传递几个参数给其后面的命令执行,例如如果xargs从标准输入中读入内容,然后以分隔符分割之后生成的命令行参数有10个,使用 -n 3 之后表示一次传递给xargs后面的命令是3个参数,因为一共有10个参数,所以要执行4次,才能将参数用完。

例:echo '11@22@33@44@55@66@77@88@99@00' | xargs -d '@' -n 3 echo 
                  输出:11 22 33
                             44 55 66
                             77 88 99
                             00

-E:该选项指定一个字符串,当xargs解析出多个命令行参数的时候,如果搜索到-e指定的命令行参数,则只会将-e指定的命令行参数之前的参数(不包括-e指定的这个参数)传递给xargs后面的命令

例:echo '11 22 33' | xargs -E '33' echo

     输出:11 22

2、sed

sed命令是一个面向字符流的非交互式编辑器,也就是说sed不允许用户与它进行交互操作。sed是按行来处理文本内容的。在shell中,使用sed来批量修改文本内容是非常方便的。

3、awk https://www.cnblogs.com/xudong-bupt/p/3721210.html

相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息,依次对每一行进行处理,然后输出

awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file

 [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value

'  '          引用代码块

BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符

//           匹配代码块,可以是字符串或正则表达式

{}           命令代码块,包含一条或多条命令

;          多条命令使用分号分隔

END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

 

特殊要点:

$0           表示整个当前行

$1           每行第一个字段

NF          字段数量变量

NR          每行的记录号,多文件记录递增

FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始

\t            制表符

\n           换行符

FS          BEGIN时定义分隔符

RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)

~            匹配,与==相比不是精确比较

!~           不匹配,不精确比较

==         等于,必须全部相等,精确比较

!=           不等于,精确比较

&&      逻辑与

||             逻辑或

+            匹配时表示1个或1个以上

/[0-9][0-9]+/   两个或两个以上数字

/[0-9][0-9]*/    一个或一个以上数字

FILENAME 文件名

OFS      输出字段分隔符, 默认也是空格,可以改为制表符等

ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕

-F'[:#/]'   定义三个分隔符

三、上述都是系统的讲述了些编写shell script的方法,下面主要介绍些常用的知识点:

1、获取变量长度:${#variable}

2、${variable:-10} 和 ${variable: -10} 有什么区别?

  • ${variable:-10} - 如果之前没有给 variable 赋值则输出 10;如果有赋值则输出该变量
  • ${variable: -10} - 输出 variable 的最后 10 个字符

3、set -e :在"set -e"之后出现的代码,一旦出现了返回值非零,整个脚本就会立即退出

4、如果mano.conf文件中的内容为

version1=1

version2=2

那么source mano.conf后$version1的值就是1,$version2的值就是2

四、数组

一、常用数组:

一般将数组分为两种数值类型,一是数值类型,二是字符串类型

表现形式为arr_number=(1 2 3 4 5);arr_string=("abc" "edf" "sss");

常用的集中操作:

  1. 获取数组长度:

arr_length=${#arr_number[*]}或${#arr_number[@]}均可,即形式:${#数组名[@/*]} 可得到数组的长度。

  1. 读取下标的值:

arr_index2=${arr_number[2]},即形式:${数组名[下标]}

  1. 对对应下标进行赋值:
  1. 如果该下标元素已经存在,会修改该下标的值为新的指定值

arr_number[2]=100,数组被修改为(1 2 100 4 5)

  1. 如果下标已经超过当前数组的大小,新赋的值被追加到数组的尾部。

arr_number[13]=13,数组被修改为(1 2 100 4 5 13)

  1. 删除操作:
  1. 清除某个元素:unset arr_number[1],这里清除下标为1的数组;
  2. 清空整个数组:unset arr_number;
  1. 分片访问

分片访问形式为:${数组名[@或*]:开始下标:结束下标},注意,不包括结束下标元素的值。

例如:${arr_number[@]:1:4},这里分片访问从下标为1开始,元素个数为4。

  1. 遍历:
  1. 遍历值:

for v in ${arr_number[@]}; do

echo $v;

done

  1. 遍历下标:

for i in ${!arr_number[@]}; do

echo $i , ${arr_number[$i]};

done

注:bash里面数组的下标,不是位置的偏移,而是具体的值,就像map的key一样;后面我们看到关联数组使用字符串作为下标。所以从for v in ${arr_number[@]}; do里面取出的值对应的下标不一定是0,1,2....要先顺序显示可以使用:

length = ${#arr_number[*]}

for index in `seq ${length}`

do

echo ${arr_number[$index ]}

done

  • 关联数组:

关联数组的索引可以是字符串,使用关联数组之前必须先声明关联数组。

声明关联数组:

declare -A ass_array

基本操作:

1、赋值:

A) 列表发赋值

ass_array=( [index1]=val1 [index2]=val2)

  1. 单独赋值

ass_array[index1]=val1

ass_array[index2]=val2

   其它操作和常用数组一样:

2、查询关联数组所有元素内容

echo ${ass_array[*]}

3、查询关联数组的索引

echo ${!ass_array[*]}

4、查询关联数组的元素个数

echo ${#ass_array[*]}

例子:关联数组(字典)操作:

#!/bin/bash
#必须先声明
declare -A dic
dic=()
while read line
do
    array=(${line//,/ })
    for var in ${array[@]}
    do
       let dic[$var]=${dic[$var]}+1
    done
done < words.txt  #如果放在前面dic[$var]就变成局部变量后续输出不了值
out_put=""
for key in ${!dic[*]}
do
     out_put=${out_put}`echo "$key ${dic[$key]}_"`
done
echo ${out_put%?} | tr '_' '\n' | sort -n -r -k 2

#!/b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值