程序员

Shell编程

2019-03-12  本文已影响0人  kangapp
字符串处理

变量string="Bigdata process framework is Hadoop,Hadoop is an open source project",执行脚本后,打印输出string字符串变量,并给出用户以下选项:

  • 打印string长度
  • 删除字符串中所有的Hadoop
  • 替换第一个Hadoop为Mapreduce
  • 替换全部Hadoop为Mapreduce
    用户输入数字1|2|3|4,可以执行对应项的功能;输入q|Q则退出交互模式
  1 #!/bin/bash
  2 #
  3 
  4 function print_tips
  5 {
  6     echo "********************************"
  7     echo "(1) 打印string长度"
  8     echo "(2) 删除字符串中所有的Hadoop"
  9     echo "(3) 替换第一个Hadoop为Mapreduce"
 10     echo "(4) 替换全部Hadoop为Mapreduce"
 11     echo "用户输入数字1|2|3|4,可以执行对应项的功能;输入q|Q则退出交互模式"
 12     echo "********************************"
 13 }
 14 
 15 function len_of_string
 16 {
 17     echo "string长度:${#string}"
 18 }
 19 
 20 function delete_all_Hadoop
 21 {
 22     echo "${string//Hadoop/}"
 23 }
 24 
 25 function replace_first_Hadoop
 26 {
 27     echo "${string/Hadoop/Mapreduce}"
 28 }
 29 
 30 function replace_all_Hadoop
 31 {
 32     echo "${string//Hadoop/Mapreduce}"
 33 }
 34 
 35 string="Bigdata process framework is Hadoop,Hadoop is an open source project"
 36 
 37 while true
 38 do
 39     echo "【string:$string】"
 40     print_tips
 41     read -p "please input your choice [1|2|3|4|Q|q]:" choice
 42     case $choice in
 43         1)
 44             len_of_string
 45             ;;
 46         2)
 47             delete_all_Hadoop
 48             ;;
 49         3)
 50             replace_first_Hadoop
 51             ;;
 52         4)
 53             replace_all_Hadoop
 54             ;;
 55         Q|q)
 56             exit
 57             ;;
 58         *)
 59             echo "请按提示输入正确的指令"
 60     esac
 61 done
命令替换

方法1:`command`
方法2:$(command)

  1 #!/bin/bash
  2 #
  3 
  4 index=1
  5 
  6 for user in `cat /etc/passwd | cut -d ":" -f 1`
  7 do
  8     echo "user${index}:${user}"
  9     index=$(($index + 1))
 10 done
有类型变量
bash数学运算expr

提示用户输入一个正整数num,然后计算1+2+3+....+num的值,必须对num是否为正整数做一个判断,不符合当允许重新输入。


  1 #!/bin/bash
  2 #
  3 
  4 while true
  5 do
  6     read -p '请输入一个正整数:' num
  7     expr $num + 1 &> /dev/null
  8     if [ $? == 0 ];then
  9         if [ `expr $num \> 0` == 1 ]; then
 10             for ((i=1;i<=$num;i++))
 11             do
 12                 sum=`expr $sum + $i`
 13             done
 14             echo "1+2+...+$num=$sum"
 15             exit
 16         else
 17             echo "输入的不是正整数"
 18         fi
 19     else
 20         echo "输入格式错误!!!!"
 21     fi
 22     continue
 23 done
bc

bash内建运算器,支持浮点数运算

函数
//第一种
function_name() 
{
  //todo
}
//第二种
function function_name
{
  //todo
}

写一个脚本,该脚本可以实现计算器的功能,可以进行四则运算

  1 #!/bin/bash
  2 #
  3 
  4 function calculator
  5 {
  6     case $2 in
  7         +)
  8             echo "$1+$3=`expr $1 + $3`"
  9             ;;
 10         -)
 11             echo "$1-$3=`expr $1 - $3`"
 12             ;;
 13         \*)
 14             echo "$1*$3=`expr $1 \* $3`"
 15             ;;
 16         /)
 17             echo "$1/$3=`expr $1 / $3`"
 18             ;;
 19     esac
 20 }
 21 
 22 calculator $1 $2 $3

todo:*号不能作为参数传递

function add
{
    echo "`expr $1 + $2`"    
}

function reduce
{
    echo "`expr $1 - $2`"
}

function mul
{
    echo "`expr $1 \* $2`"
}

function div
{
    echo "`expr $1 / $2`"
}

function sys_load
{
    echo "Memory Info"
    echo
    free -m
    echo

    echo "Disk Usage"
    echo
    df -h
    echo
}

. bash_function.lib(加点引用),shell中取绝对路径
可以直接使用库函数 :add 3 4

find 命令

语法格式:find [路径] [选项] [操作]

选项
命令

将/var/log/目录下以log结尾的文件,且更改时间在7天以上的复制到/root/conf/目录下
find /var/log/ -type -f -name '*log' -mtime +7 -exec cp {} /root/conf/ \;

locate命令

在数据库文件中查找
更新数据库updatedb

whereis命令
which命令
grep命令

语法格式:
grep [option] [pattern] [file1,file2....]
command | grep [option] [pattern]

option
sed命令

语法格式:
sedout | sed [option] "pattern command"
sed [option] "pattern command" file

option
pattern 匹配模式
command 编辑命令

打印

增加

删除

修改

案例1:输入mysql的my.cnf文件,根据段名输出该段包含项的数量
1 mysqld 4
2 mysqld_safa 2

  1 #!/bin/bash
  2 #
  3 
  4 MYSQLCONF_NAME=/root/linux_test/test/my.cnf
  5 
  6 function get_all_segments
  7 {
  8     echo "`sed -n '/\[.*\]/p' $MYSQLCONF_NAME|sed -e 's/\[//g' -e 's/\]//g' `"
  9 }
 10 
 11 function count_items_in_segment
 12 {
 13     sum=`sed -n '/\['$1'\]/,/\[.*\]/p' $MYSQLCONF_NAME|grep -v '\[.*\]'|grep -v '^$'|grep -v '^#'|wc -l`
 14     echo "$sum"
 15 }
 16 
 17 index=0
 18 for item in `get_all_segments`
 19 do
 20     index=`expr $index + 1`
 21     echo "$index:$item  `count_items_in_segment $item`"
 22 done

案例二:删除配置文件中的所有注释行和空行
sed -i '/[:blank:]*#/d' nginx.conf

案例三:在配置文件中所有不以#开头的行前面添加*符号
sed -i 's/^[^#]/\*&/g nginx.conf'

awk命令

语法格式:
awk -f 文件名
awk 'BEGIN{}pattern{commands}END{}' file_name
standard output | awk 'BEGIN{}pattern{commands} END{}'

内置变量
printf
格式符 含义
%s 打印字符串
%d 打印十进制数
%f 打印浮点数
%x 打印十六进制数
%o 打印八进制数
%e 打印数字的科学计数法
%c 打印单个字符的ASCII码
%s 打印字符串

awk 'BEGIN{FS=":"} {printf "0.2%f\n",$3}' /etc/passwd

修饰符 含义
- 左对齐(默认右对齐)
# 显示8进制在前面加0,显示16进制在前面加0x

awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' /etc/passwd
awk 'BEGIN{FS=":"} {printf "%-12d\n",$3}' /etc/passwd

pattern模式匹配

匹配/etc/passwd文件行中含有root字符串的所有行
awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
匹配/etc/passwd文件行中以yarn开头的所有行
awk 'BEGIN{FS=":"}/^yarn/{print $0} /etc/passwd'

匹配/etc/passwd文件行中第3个字段小于50的所有行
awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
匹配/etc/passwd文件行中第7个字段等于/bin/bash的所有行
awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
匹配/etc/passwd文件行中第3个字段包含3个以上数字的所有行
当出现{x,y}次数匹配,需加上--posix或--re-interval
awk --posix 'BEGIN{FS=":"} $3~/[0-9]{3,}/{print $0}' /etc/passwd

匹配/etc/passwd文件行中第1个字段包含hdfs或yarn的所有行
awk 'BEGIN{FS=":"}$1=="hdfs"||$1=="yarn"{print $0}' /etc/passwd
匹配/etc/passwd文件行中第3个字段和第4个字段同时包含3个以上数字并且的所有行
awk --re-interval 'BEGIN{FS=":"} $3~/[0-9]{3,}/&&$4~/[0-9]{3,}/{print $0}' /etc/passwd

条件表达式和循环表达式

awk 'BEGIN{FS=":"}{if($3>50) {print "$3>50",$3} else {print "$3<50",$3}}' /etc/passwd
三种循环(while/ do while/ for())
awk '{num=NF-1;for(i=2;i<=NF;i++){sum=sum+$i};AVG=sum/num;sum=0;print AVG}' ipAddress

字符串函数
函数 功能
length(str) 计算长度
index(str1,str2) 返回str1中查询到的str2的位置
tolower(str) 小写转换
toupper(str) 大写转换
split(str,arr,fs) 分割字符串,并保存到arr中,返回数量
match(str,RE) 返回正则表达式匹配到的子串位置
substr(str,m,n) 截取子串,从m开始截取n位
sub(RE,RepStr,str) 替换查找到的第一个子串,返回替换的个数
gsub(RE,RepStr,str) 替换查找到的所有子串,返回替换的个数

以:为分隔符,返回/etc/passwd中每行的各个字段的长度
awk '{num=split($0,arr,":");for(i=1;i<=num;i++){printf "%d ",length(arr[i])};print ""}' /etc/passwd

[option]
数组

统计主机上所有Tcp连接状态数,按照每个Tcp状态分类
netstat -an | grep tcp | awk '{array[$6]++}END{for(i in array) print i,array[i]}'

计算横向数据综合,计算纵向数据总和

  1 BEGIN{
  2     printf "%-8s%-8s%-8s%-8s%-8s%-8s\n","name","A","B","C","D","AVG"
  3 }
  4 {
  5     printf "%-8s",$1
  6     sum=0;
  7     avg=0;
  8     for(i=2;i<=5;i++)
  9     {
 10         printf "%-8d",$i
 11         sum=sum+$i
 12         array[i]=array[i]+$i
 13     };
 14     avg=sum/NF
 15     printf "%-8.2f\n",avg
 16 }
 17 END{
 18     printf "%-8s%-8d%-8d%-8d%-8d\n","Total",array[2],array[3],array[4],array[5]
 19 }
上一篇下一篇

猜你喜欢

热点阅读