`
ginge
  • 浏览: 211939 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

实战Shell脚本—sed,awk使用

阅读更多

 

先让大家看一个脚本:

#!/bin/sh

 

start_time=${1:-19:00}

amount=${2:-1000}

total_runtime=${3:-1}

runinterval=${4:-1}

 

BASE="/home/wolf/ezra/deploy/target/bundle-ear"

LOCAL_CLASSPATH=`echo $BASE/*.jar | tr ' ' ':'`

CLASSPATH="/usr/repos/repository.external/java/j2ee/j2ee-1.4.jar:$LOCAL_CLASSPATH"

 

if [ -n "`ps -ef | grep java |grep task`" ];then

  echo "task has been run before, refuse to run another task instance." >> /home/wolf/output/daemon/usr/task.log

  exit -1;

fi

 

java -DtaskName=task -cp $CLASSPATH -Dapplication.codeset=GBK -Ddatabase.codeset=ISO-8859-1 -Xms64m -Xmx1024m -server com.daemon.offer.Task $start_time $amount $total_runtime $runinterval &

 

 

  看到什么问题没?脚本是没有问题的,对吧。只是如果摆放程序的位置发生变化,至少有几个地方是需要修改的。这包括程序所在目录,第三方类库的目录以及日志文件目录的信息。

 

  那么是不是就留着让它继续这样下去吗?当然是可以的,只要你能忍受无休止的重复劳动,而本来你可以用做这些无聊的事情时间去做更多有意义的事情!

 

  假设我们有个项目属性文件可以提供这些信息,那么我们现在要做的事情就是想办法从这个属性文件里面将这些配置读取出来。读取配置是容易的,因为配置里面都是一些键值对。这个用grep或者sed以或者用awk都能比较简单方便的取出来。可是这里有个难题,怎么解决属性值嵌套问题呢?例如下面的代码:

deployhome  = ${homepath}/deploy

homepath  = /usr/ ${project}/416

project=anthrex

 

  好了,先解决第一个问题,看看以下段代码:

function getValue()

{

   echo "`sed -e 's/^#.*//' < $2| sed -n 's/.*'$1'[\ ]*=[\ ]*//p'`"

}

 

JAVA_HOME="`getValue javahome $properties`";

SECOND_REPOSITORY="`getValue project $properties`"

THIRD_REPOSITORY="`getValue external $properties`"

HOME_PATH="`getValue homepath $properties`";

OUTPUT="`getValue output $properties`"

 

bash shell里面是允许有函数的,与Java的函数不同之处就是,方法参数是不需要声明的。上面这段脚本里面,核心是getValue函数,不用声明函数参数,调用时直接指定就可以的。这个函数很简单,利用sed对输入的每行字符做了两个替换动作。

 

 

sed -e 's/^#.*//'

命令中字符s告诉sed要进行替换操作。/是分隔符,第一个分隔符后面指定了^#.*,要替换的行就是注释的行,第二和第三个是空字符。也就是先忽略掉注释的行。

 

 

sed -n 's/.*'$1'[\ ]*=[\ ]*//p'

  这个与第一个sed命令不同是-e变成了-n,就是默认不打印所匹配的模式使用了这个参数,在整个命令的后面通常都会跟p打印指令。-e是运行脚本。这个命令是要将匹配的键值找出来,并且把空格去掉。如果$1java.home,那么这个命令就可能找到java.home  =  /usr/java这一行,最后得到/usr/java

 

好了,通过上述改造,脚本只需要输入项目Properties文件文件就可以了,其他参数自动生成。

 

 

  这个问题是完全结束了,可是要是属性值里引用了其他键值,例如

upload.temp  = ${output}/temp

,这个脚本就没辙了。要是也能做到像Spring里面的PropertiesConfigure实现那样该多好啊!

 

显然,要简单的想用shell或者sed来实现这个功能已经不容易了,起码会很费劲。这里我想起了awk里面的Associative Array,关联数组,说白了这个与Java里面的Map非常类似。利用这特点就可以将属性值里面的引用扩展了。

cat $1 | sed -e 's/^#.*//g' -e 's/[ ]*//g' | gawk -f ./expan.sh > properties

properties=./properties

 

function getValue()

{

   sed -n 's/.*'$1'[\ ]*=[\ ]*//p' < $2;

}

 

JAVA_HOME="`getValue javahome $properties`";

SECOND_REPOSITORY="`getValue project $properties`"

THIRD_REPOSITORY="`getValue external $properties`"

HOME_PATH="`getValue homepath $properties`";

OUTPUT="`getValue output $properties`"

 

 

这个脚本与之前的脚本最大的不同在于引入了awk,先把注释行替换才丢给awk处理。再来看看这个expan.sh

#!/bin/gawk -f

#written by Ginge

BEGIN{

  FS="=";

}

{

 if(NF ==2)

  {

    map[$1]=$2;

  }

}

END {

  expan(map);

 

  for(i in map){

    print i"="map[i];

  }

}

 

function expan(map){

  for (i in map) {

  val=map[i];

  left=index(map[i], "{");

  right=index(map[i],"}");

  subkey="";

  if(left > 0 && right > 0){

      subkey=substr(map[i],left+1,right-left-1);

      if(length(map[subkey]) > 1){

          val=map[subkey]""substr(map[i],right+1,length(map[i]));

          map[i]=val;

          if(index(map[i],"{") > 0)

            expan(map);

       }

    }

  }

}

 

看上去还是很简单的吧,第一行声明了这是一个gawk(用gawk是为了要使用它的用户自定义function特性)脚本。

 

 

Awk默认以空格来分离每行的输入,上述脚本在BEGIN代码块指明了用=来分离。这样

javahome=/user/Java/jdk1.5.0_17

这行输入就被分成了javahome/user/Java/jdk1.5.0_17,用位置参数可以访问到这些分离之后的值。例如$1的值是javahome$2/user/Java/jdk1.5.0_17,以此类推。

 

 

BEGINEND代码块是可选的,这些代码只调用一次,中间中括号之间的map[$1]=$2就是关联数组了;它对每个输入都是执行一次的。结合BEGIN和中间的代码块,我们就做到了map[javahome]= /user/Java/jdk1.5.0_17这样的效果。如何扩展属性看看那个附件的expan函数就知道了。

 

到这里改造完成了。

deployhome  = ${homepath}/deploy

homepath  = /usr/ ${project}/416

project=anthrex

 

通过脚本改造后可以得到这样的结果

deployhome= /usr/ anthrex /416/deploy

homepath= /usr/ anthrax/416

project=anthrex

 

 

到此我们实战了sed的简单用法和awk的高级功能关联数组,看来shell脚本还是比较好玩的。

0
0
分享到:
评论

相关推荐

    Linux主要shell命令、sed、awk使用详解

    Linux 主要shell命令、sed、awk使用详解 Linux 主要shell命令详解 shell 是用户和 Linux 操作系统之间的接口。Linux 中有多种 shell,其中缺省使用的是 Bash。本章讲述了 shell 的工作原理,shell 的种类,shell ...

    shell脚本修改json中某个字段的值

    下面是一个基本的shell脚本示例,演示如何使用awk和sed修改JSON文件中的某个字段值: ```bash #!/bin/bash # 定义要修改的JSON字段名和新的值 field_to_change="name" new_value="新名称" # 使用awk定位含有字段...

    Shell脚本专家指南.sed与awk第二版.shell十三问

    本文将深入探讨"Shell脚本专家指南"、"sed与awk第二版"以及"shell十三问"这三份文档所涵盖的重要知识点。 首先,"Shell脚本专家指南"详细介绍了如何编写高效且实用的Shell脚本。这包括了对Bash Shell的深入了解,如...

    sed awk高级编程案例

    通过这些案例,我们可以看到sed和awk这两个强大的文本处理工具在Linux shell脚本中的广泛应用。sed作为一个流编辑器,擅长于对单行文本进行快速处理和转换,而awk则是一个更复杂的文本分析工具,适用于将文本文件...

    shell编程,sed,awk,grep等教程整理

    Shell脚本允许用户通过命令行界面执行一系列自动化任务,极大地提高了工作效率。本文将深入探讨shell编程,以及与之紧密相关的sed、awk和grep命令,这些都是Linux系统中进行文本处理和数据操作的重要工具。 首先,...

    Sed与awk第二版(中文高清版)

    3. 自动化脚本:在shell脚本中嵌入sed和awk命令,实现复杂的文本处理功能。 在学习Sed和awk时,读者需要注意,这些工具依赖于正则表达式进行文本匹配。因此,熟悉正则表达式的语法和使用方法对掌握sed和awk至关重要...

    UNIX Shell awk sed 实例 精解 (第4版)

    在IT领域,尤其是在Linux系统管理中,Bash Shell、awk和sed是不可或缺的工具,它们在文本处理和自动化任务执行方面发挥着重要作用。本指南将深入解析这些工具的使用实例和精解,帮助读者理解并掌握这些强大的命令行...

    sed awk学习

    SED 和 Awk 都可以用 -f 来指定工作内容,这通常就是脚本存放的位置。在 sed 和 awk 中,每个指令都包含两个部分,模式和语句。模式是由 / 分隔的正则,语句指定一个或多个将被执行的动作。 SED 的语句由类似于行...

    shell中的精髓_sed_awk

    ### 关于Shell中的sed与awk #### 一、引言 在Unix及类Unix系统(如Linux)中,`sed` 和 `awk` 是两个极其强大的文本处理工具,被广泛应用于脚本编写、数据处理以及各种自动化任务中。本文旨在深入探讨这两个工具的...

    Sed AWK编程指南

    在 `sed` 脚本中可以使用 `#` 添加注释。 示例: ``` sed -f script.sed file.txt # 这是一条注释 ``` ##### 26. `sed` 作为解释器 `sed` 可以作为一个解释器来执行脚本,这对于批量处理非常有用。 示例: ``` ...

    shell awk sed

    在IT领域,shell、awk和sed是三种非常重要的命令行工具,它们在Linux和Unix系统中扮演着核心角色。...掌握shell、awk和sed的使用,了解设备驱动开发和内核原理,将极大地提升你在系统管理和软件开发方面的技能。

    Shell编程高级进阶系列视频.zip

    目录网盘文件永久链接 13Linux下Shell编程之While case...25Shell脚本编程综合实战一 26Shell脚本编程综合实战一 27Shell脚本综合实战二 28Shell脚本综合实战二 29Shell编程数组编程及复习 30Shell编程数组编程及复习

    shell脚本初学者使用

    Shell脚本中可以使用正则表达式进行模式匹配,常见的命令如grep、sed、awk等。 #### 13. 管道与重定向 管道(|)将一个命令的输出作为另一个命令的输入;重定向(&gt;、&lt;、&gt;&gt;)用于控制命令的标准输入输出。 #### 14....

    Shell 脚本编程实战100例.pdf

    从提供的文件内容来看,这是一本关于Shell脚本编程的实战教程书籍,以实例的方式教授读者如何使用Shell脚本来完成各种Linux系统运维任务。下面将详细介绍从给出的内容中能够总结出的一些Shell脚本编程知识点。 首先...

    Bash+Sed+Awk(1).pdf

    文本处理是Shell脚本中的重要部分,Sed和Awk是处理文本的两个强大工具。Sed通过流编辑器的方式处理文本,而Awk则是一种编程语言,用于对文本和数据进行模式扫描和处理。 - **Sed的使用**:本书详细介绍了Sed的基本...

    shell编程指南,shell脚本,本书共分五部分全。grep家族,sed,AWK,正则表达式,tr用法

    第16章 shell脚本介绍 151 第17章 条件测试 154 第18章 控制流结构 160 第19章 shell函数 202 第20章 向脚本传递参数 224 第21章 创建屏幕输出 236 第22章 创建屏幕输入 252 第23章 调试脚本 274 第24章 shell嵌入...

Global site tag (gtag.js) - Google Analytics