shell script编程小结——附带实例

虚烬
• 阅读 3642

shell script编程小结

前言

shell作为编程中不可或缺的一部分,平日里,我们经常会在shell中输入一些命令。有时候也需要完成一些复杂的操作,重复的输入多条相同的命令,过于费时和无趣。所以掌握shell script就显得非常有必要了,可以让你用编程的方式调用繁多的命令行工具。

最近,正好碰上一个一直拖着的需求,便抄起了shell解决掉了,写了人生中第一段shell script代码。

需求如下

从一个文件夹中获取一个文本,这个文本里记录了链接以及他对应的版本号。并到另外一个html文件夹中遍历所有html文件,将其中的链接中的@VERSION替换为相应的版本号。

流程

  1. 创建一个shell脚本,例如touch test.sh

  2. 在命令行中输入chmod +x ./test.sh,使这个文件变成一个可执行文件

  3. 在这个脚本文件中书写代码,诸如"find ."

  4. 在命令行中输入./test.sh,即可运行。

  5. 结果,输出当前目录下所有文件夹与文件的名称

shell script介绍

和所有的编程一样,shell脚本主要由自身语法,以及繁多的linux命令构成。我们只需要学习shell脚本自身的语法以及一些常用的linux命令即可,需要的时候可以查询相应的linux命令。

shell script语法

因为篇幅限制,所以仅列出提纲,具体的学习可以参考文末的参考资料

  • 变量

  • 数组

  • 传参

  • 运算符

  • 输入输出以及重定向

  • 测试 test

  • 流程控制

  • 函数

  • 文件包含

linux命令

linux命令是linux强大的一个重要基础,分为以下5个部分。编程中,用对了指令可以减少许多工作。也正因为繁多的指令,给shell脚本带来了足够的能力。

  • 系统管理

  • 网络管理

  • 软件 | 打印 | 开发 | 工具

  • 文件目录管理

  • 硬件 | 监测 | 内核 | Shell

实例讲解

代码分为三个函数,第一个配置初始化函数init(),第二个遍历文件夹函数walk(),第三个是对html文件的处理函数,运用sed正则替换html中的链接html_into_ver()

想要实际操作的可以拿这个kindle文字伴侣进行测试,这个项目是用去哪儿的前端构建工具fekit构建的。脚本名字为export_html,可以在命令行中输入./export_html进行测试,会多出一个export_html的文件夹,里面存放着所有的输出html文件。

github项目地址

配置函数init()

这一部分主要是默认配置的设置

function init()
{
  # html_into_ver配置区
  de_reg_rule="\(.*\)\(http://localhost/kindleClipingDeal/prd/\)\(.*\)\(@VERSION\)\(.*\)\".*"
  de_cur_prefix="http://localhost/kindleClipingDeal" #当前prd前面的路径
  de_replace_prefix="http://wilsonliu.cn/kindleClipingDeal" #当前前缀替换后路径
  de_ver_file="ver/versions.mapping"  #当前存储版本号码的文件

  de_target_dir="export_html" #将html修改后,输出的目标文件夹
  de_source_dir="html" # 源文件夹为html

  # 如果目标文件夹存在,则先删除
  if [ -e ${de_target_dir} ]; then
    rm -rf ${de_target_dir}
  fi
  #首先复制源文件夹为输出文件夹,在输出文件夹
  cp -rf ${de_source_dir} ${de_target_dir}

  # walk 的3个参数配置
  de_dir_to_walk=${de_target_dir} #将要遍历操作文件夹
  de_walk_file_callback="html_into_ver" #文件处理回调函数
  de_walk_dir_callback="" #文件夹处理回调函数,非必要,可为空

  # 调用walk函数
  walk $de_dir_to_walk $de_walk_file_callback $de_walk_dir_callback
}
init; # 程序初始化执行

遍历文件夹函数walk()

<!-- #!/bin/bash -->

# walk 函数 三个配置
# 第一个是遍历的目标文件,第二个是对文件处理的调用函数,第三个是对文件夹处理的调用函数,
# 调用函数 有两个输入一个是遍历的文件夹,一个是当前文件夹
function walk()
{
  # ${1}为调用walk函数时传入的第一个参数
  for file in `ls ${1}` #ls输出当前路径下的所有文件以及文件夹,利用for in分别对其进行操作
  do
    path=${1}"/"${file} #拼接当前将要处理的文件或文件夹路径
    if [ -d ${path} ]  #-d 是测试其是否是文件夹
     then
      #  如果存在回调函数,则调用文件处理回调函数 并且输入遍历的目标文件夹以及当前文件夹路径
      if [ ${3} ] # ${3} 即为调用walk时输入的第三个参数,应该为文件夹处理函数
      then
        $3 $1 ${path} #调用${3}指向的函数,并传入当前所在路径以及要处理的文件夹路径
      fi
      # 对当前文件夹继续调用walk函数
      walk ${path} $2 $3 #遍历文件夹
    else
      # 调用文件处理函数对文件进行处理,并输入遍历的目标文件夹以及当前文件路径
      $2 $1 ${path}
    fi
  done
}

html文件处理函数html_into_ver()

利用sed流编辑器进行正则匹配与替换

# 将html中的所有链接中的 VERSION 改为正确的版本号码
function html_into_ver()
{
  # 获取当前$2的html文件内所有的链接地址
  link=`sed -n "s#${de_reg_rule}#\2\3\4\5#p"  $2`
  # 获取当前$2的html文件内所有的连接路径
  link_path=`sed -n "s#${de_reg_rule}#\3\5#p" $2`

  i=1
  while [ `echo ${link} | cut -d " " -f $i` ]; do
    cur_link=`echo ${link} | cut -d " " -f $i` #html中的完整路径
    cur_link_path=`echo ${link_path} | cut -d " " -f $i` #html中的完整路径

    cur_version=`sed -n "s*${cur_link_path}#**p" ${de_ver_file}` #当前文件的版本号
    cur_replace_link=`echo ${cur_link} | sed -n   "s#\(.*\)\(@VERSION\)\(.*\)#\1@${cur_version}\3#p"` #当前替代cur_link的链接
    #因为sed -i这个命令在mac与linux上存在差异,mac上强制要求sed -i 后多一个参数用来指替备份文件名,可以用空字符来解决,mac上输出为Darwin,依次判断
    if [ `uname -s` == "Darwin" ]; then
      sed -i ""  "s#${cur_link}#${cur_replace_link}#" ${2} #直接对当前文件进行VERSION修改
    else
      sed -i     "s#${cur_link}#${cur_replace_link}#" ${2} #直接对当前文件进行VERSION修改
    fi
    # 循环的条件
    i=`expr $i + 1`
  done
  #统一修改链接前缀
  if [ `uname -s` == "Darwin" ]; then
    sed -i "" "s#${de_cur_prefix}#${de_replace_prefix}#g" ${2}  #修改链接的前置部分
  else
    sed -i "s#${de_cur_prefix}#${de_replace_prefix}#g" ${2}  #修改链接的前置部分
  fi
}

写在最后

shell编程的好处在于可以批量化自动化操作以提高开发效率,同时也可以用来解决许多问题,本身并不复杂,简单易学,功能强大。
希望大家都能够掌握这一工具。

参考资料

WilsonLiu's blog首发地址:http://blog.wilsonliu.cn

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
可莉 可莉
3年前
0615 shell编程1
0615shell编程1一、shell脚本介绍shell是一种脚本语言和传统的开发语言比较,会比较简单shell有自己的语法;可以使用逻辑判断、循环等语法可以自定义函数,目的就是为了减少重复的代码shell是系统命令的集合
Stella981 Stella981
3年前
Linux基础(1)之shell
  shell作为下Linux系统中用户与内核交互的接口,用于将用户输入的命令转化为内核可以理解的指令,进而通过内核操作硬件资源,完成相应的功能。shell分为两种,图形shell和命令行shell。图形shell主要有KDE,Gnome等,命令行shell有常见的sh,zsh,csh,bash,ksh,tcsh等。  这里主介绍最常用的bash
Stella981 Stella981
3年前
Linux查看内置命令和非内置命令帮助的几种方法(man、help、info)
!(https://oscimg.oschina.net/oscnet/53cb7c40ce2945df9de5490f1d07e660.jpg)内置命令就是shell内核自带的,因为shell当中自己要进行管理,那么就需要一些命令进行管理,不同的shell肯定有不同的shell命令,我们用type命令就可以看到其的类型,内置shell命令其
Stella981 Stella981
3年前
0615 shell编程1
0615shell编程1一、shell脚本介绍shell是一种脚本语言和传统的开发语言比较,会比较简单shell有自己的语法;可以使用逻辑判断、循环等语法可以自定义函数,目的就是为了减少重复的代码shell是系统命令的集合
Stella981 Stella981
3年前
HBase启动失败
如果在hbase的shell中输入了status报错,hbase(main):001:0statusERROR:org.apache.hadoop.hbase.ipc.ServerNotRunningYetException:Serverisnotrunningyetatorg.apache.ha
Stella981 Stella981
3年前
Linux云计算学习笔记day56
shell编程第一章1.1什么是shell?Shell其实是一个命令解释器,作用是解释执行用户输入的命令以及程序等,用户每输入一条命令,Shell给予解释执行一条。这种键盘一输入命令,就可以立即得到回应的对话方式,称为交互模式。Shell存在于操作系统的最外层,负责与用户直接对话。处理用户的输入,并将操作系
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这