Shell工具| 流程控制

1. 流程控制

if 判断

复制代码
1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格

[kris@hadoop datas]$ vim if.sh 
#!/bin/bash
if [ $1 -eq "1" ]
then
        echo "one"
elif [ $1 -eq "2" ]
then
        echo "two"
else
        echo "other"
fi
-------------------
#!/bin/bash
if [ $1 -eq "1" ]; then echo "one"
fi
复制代码

 

运算式$[4%2] 和表达式[ 4 -eq 3 ],注意区别

for循环和if的使用

复制代码

表达式
[kris@hadoop datas]$ vi for.sh 
#!/bin/bash

for ((i=0;i<10;i++))
do
        if [ $[$i%2] -eq 0 ]
        then
        echo $i
fi
done

或者这样写:
for ((i=0;i<10;i++))
do
        if [ $(($i%2)) = 0 ]; then echo $i
     fi
done

[kris@hadoop datas]$ sh for.sh 
0
2
4
6
8

#!/bin/bash
for((i=0;i<10;i++))
do
        if [ $(($i%2)) = 0 ]; then echo $i
        elif [ $(($i%3)) = 0 ]; then echo $i
        else echo "我是奇数"
fi
done
复制代码

case

复制代码
#!/bin/bash
case $1 in
"1")
        echo "Monday"
;;
"2")
        echo "Tuesday"
;;
"3")
        echo "Wednesday"
;;
"4")
        echo "Thursday"
;;
"5")
        echo "Friday"
;;
*)
        echo "Weekend"
;;
esac

[kris@hadoop datas]$ ./case.sh 3
Wednesday
复制代码

 while循环

复制代码
[kris@hadoop datas]$ vim while.sh 
#!/bin/bash
i=1
s=0
while [ $i -le 100 ]
do
  s=$[$s+$i]
  i=$[$i+1]
done
echo $s
[kris@hadoop datas]$ sh while.sh 3333333333
5050
复制代码

 

read读取控制台输入

复制代码
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
    变量:指定读取值的变量名

#/bin/bash
read -p "Please input a num in 5 seconds:" a
echo $a
复制代码

 

函数function

bash 可以进入子shell,exit是退出来,

source a.sh是在当前shell执行
./a.sh是在子shell中执行的

export 使得当前shell和子shell中定义的变量都起作用

 系统函数

复制代码
basename [string / pathname] [suffix] 
(功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

[kris@hadoop datas]$ basename /home/kris/datas/while.sh
while.sh
[kris@hadoop datas]$ basename /home/kris/datas/while.sh .sh
while

dirname 文件绝对路径        (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
[kris@hadoop datas]$ dirname /home/kris/datas/while.sh  
/home/kris/datas
复制代码

自定义函数

复制代码
必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

#/bin/bash
function sum()
{
        s=$echo $s
}
sum $1 $2
~                                                                               
~                                                                                                           
[kris@hadoop datas]$ 
[kris@hadoop datas]$ sh function.sh 1 3
4
复制代码

2. shell工具

cut

cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

-f (列号,提取第几列)   -d(分隔符,按照指定分隔符分割列)    -c   (指定具体字符,如5--9个字符)

复制代码

[root@kris datas]# ifconfig | grep Bcast 
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
[root@kris datas]# ifconfig | grep Bcast | cut -c 11-14
inet

[root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2
192.168.1.100  Bcast
[root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 1 
192.168.1.100
[root@kris datas]# ifconfig | grep Bcast > temp.log  ##### > 是把原来的内容覆盖、>>是在原内容基础上追加; 
[root@kris datas]# cat temp.log 
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
[root@kris datas]# cut -d : -f 2 temp.log          
192.168.1.100  Bcast
[root@kris datas]# cat temp.log | cut -d : -f 2  #####与上边是的等效的,只是temp.log所放的位置不一样
192.168.1.100  Bcast
[root@kris datas]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 3
Bcast
复制代码

 

 sed

sed按行处理;

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出

 -e(直接在指令列模式上进行sed的动作编辑;两个修改指令的方式)  -i (在文件中直接编辑修改文件)   

a(新增,a的后面可以接字串,在下一行出现 '2axxxx' )  d (删除)

 s(查找并替换 ‘s/Link/xxxx/’ 

复制代码
ifconfig | sed '1d'    删除第一行

 ifconfig | sed '1,5d' 删除掉前5行

 ifconfig | sed '1akris'  在第一行后面(第二行)追加kris

ifconfig | sed 's/Link/XXX/' 查找并替换;注意是区分大小写的,最后的/符号不要忘记了ifconfig | sed 's/Link/XXX/' temp.log  #并不会改变文件内容

 ifconfig | sed -i 's/Link/XXX/' temp.log  加上-i就可以在文件中修改成功了;前提是文件中的内容必须是ifconfig输出内容;
ifconfig | sed  '/^ *R/aXXX'  前边有若干个空格,以R开头的

[root@kris datas]# ifconfig | sed -e '/^ *R/aXXX' -e'/^ *T/d'   
以R开头的追加XXX
,把以T开头的删掉;这是两个式子就不能通过一个式子搞定了,需加-e改变修改方式只有一个时可以省略;
复制代码

 

 awk

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

按行处理,可以对行内的数据进行更细微的操作;

awk [选项参数] ‘pattern1{action1}  pattern2{action2}...’ filename

  pattern:表示AWK在数据中查找的内容,就是匹配模式

  action:在找到匹配内容时所执行的一系列命令

  选项参数:-F(指定输入文件折分隔符)、-v(赋值一个用户定义变量)

复制代码
cp /etc/passwd ./
[root@kris datas]# cat passwd | awk '/^a/{print}' 把以a开头的打印出来 [root@kris datas]# cat passwd | awk '/^a/{print}'   adm:x:3:4:adm:/var/adm:/sbin/nologin   avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin   abrt:x:173:173::/etc/abrt:/sbin/nologin   apache:x:48:48:Apache:/var/www:/sbin/nologin [root@kris datas]# cat passwd | awk -F : '/^a/{print $1}' //-F指定输入文件折分隔符   adm   avahi-autoipd   abrt   apache [root@kris datas]# cat passwd | awk -F: '/^a/{print $1} /^adm/{print}' 如果匹配到了以a开头就把print $1打印出来; 如果又匹配到了adm就把print整行打印出;

  adm
  adm:x:3:4:adm:/var/adm:/sbin/nologin
  avahi-autoipd
  abrt
  apache
  alex

#如果不写模板它就把所有行都打印出
[root@kris datas]# cat passwd | awk -F : '{print $1}'   ...... [root@kris datas]#
cat passwd | awk -F: 'BEGIN{print "begin"} {print$1} END{print "end"}'
  #begin在数据输入之前先执行BEGIN这个块里边的;END是所有数据处理完了再执行这个块里边的东西;
  begin
  ...
  end

 [kris@hadoop datas]$ cat passwd
  root:x:0:0:root:/root:/bin/bash
  bin:x:1:1:bin:/bin:/sbin/nologin
  daemon:x:2:2:daemon:/sbin:/sbin/nologin
  adm:x:3:4:adm:/var/adm:/sbin/nologin
  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  sync:x:5:0:sync:/sbin:/bin/sync
  shutdown:x:6:0:sh.....

[root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3} END{print "Sum="sum}'  #把第3列的数值加到sum上,对文件的第3列做累加;
  Sum=0
  Sum=3222
[root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}' ###上面求和的过程


[root@kris datas]# which awk
/bin/awk
[root@kris datas]# ll /bin/awk
lrwxrwxrwx. 1 root root 4 9月   3 2013 /bin/awk -> gawk  
[root@kris datas]# cat passwd | awk -F: -v sum=0 'BEGIN{print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}'  #-v就是引入一个变量


awk的内置变量
[root@kris datas]# cat temp | awk 'BEGIN{sum=0}{sum+=1}/^$/{print sum}'  #打印出文件的所有空行的行号,下面这种方法更简单;

[root@kris datas]# cat temp | awk '/^$/{print NR}' #NR就起到sum的作用; 也可这样写: awk '/^$/{print NR}' temp
2
3
5
7
8
10
11
12

[root@kris datas]# awk '/^$/{print FILENAME}' temp  ##每列输出文件名
temp
temp
temp


[root@kris datas]# awk -F : '{print NF}' passwd   #######NF是按:切割的列数,一共多少列;  
7
7
7
...

[root@kris datas]# awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:"NF}' passwd 
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7
[root@kris datas]# ifconfig  eth0 | grep "inet addr" | awk -F: '{print $2}'
192.168.1.100  Bcast
[root@kris datas]# ifconfig  eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'
192.168.1.100
复制代码

 

复制代码
一个目录下(包括子目录)一共有多少个java文件? 如何取得每一个文件的名称? 
[kris@hadoop ~]$ sudo find / -name "*.java"
/root/anaconda3/pkgs/spyder-3.3.2-py37_0/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
/root/anaconda3/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
[kris@hadoop ~]$ sudo find / -name "*.java" | awk -F "/" '{print $NF}'  以/切割,NF这行一共有多少列,如一共8列,$NF表取第8列
example.java
example.java

 [kris@hadoop ~]$ basename /opt/module/hive
  hive

 
复制代码

 

 practice 

使用Linux命令查询file1中空行所在的行号
[krs@hadoop101 datas]$ awk '/^$/{print NR}' file1.txt 
5
复制代码
1.有文件chengji.txt内容如下:
张三 40
李四 50
王五 60

使用Linux命令计算第二列的和并输出
[kris@hadoop datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'   ######### -F " " $2 分割的列不是从0开始数的,从1开始
150

2.用shell写一个脚本,对文本中无序的一列数字排序
[kris@hadoop datas]$ sort -n text.txt 
1
2
3
4
5
6
7
8
9
10

[kris@hadoop datas]$ sort -n text.txt | awk '{sum+=0;print0;print 0} END{print "sum="sum}'

  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
  sum=55

3 用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”kris”的文件名称
  [kris@hadoop datas]$ grep -r "kris" /home/ | cut -d : -f 1
复制代码

 

sort

-n(依照数值的大小排序) 、  -r (以相反的顺序来排序) 、 -t (设置排序时所用的分隔字符) 、 -k(指定需要排序的列)

复制代码
[root@kris datas]# cat passwd | grep ^a | sort -t : -k 3
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
[root@kris datas]#
cat passwd | grep ^a | sort -t : -k 3 -n   adm:x:3:4:adm:/var/adm:/sbin/nologin   apache:x:48:48:Apache:/var/www:/sbin/nologin   avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin   abrt:x:173:173::/etc/abrt:/sbin/nologin
[root@kris datas]#
cat passwd | grep ^a | sort -t : -k 3 -nr abrt:x:173:173::/etc/abrt:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin [root@kris datas]# sort -t : -nrk 3 sort.sh bb:40:5.4 bd:20:4.2 cls:10:3.5 xz:50:2.3 ss:30:1.6



 

复制代码
posted @ 2020-02-19 11:00  啊啊啊啊鹏  阅读(73)  评论(0编辑  收藏  举报
1 2