grep命令的模式十分灵活,算术代换

作者: 操作系统  发布:2019-11-09

Shell历史

  • Shell的功用是分解顾客的下令,客商输入一条命令,Shell就表明履行一条,那条办法叫做交互作用式(interactive),Shell还恐怕有大器晚成种施行命令的法门叫做批处理(batch),客户优先写一个Shell脚本(script),在那之中有好多条命令,让Shell叁遍把那个命令实践完,而不必一条条地敲命令。Shell脚本和编制程序语言肖似,也可以有变量和流程序调控制语句,但Shell脚本是分解实行的,无需编写翻译,Shell程序从剧本中生龙活虎行生机勃勃行读取并奉行那个命令,相当于三个客商把脚本中的命令豆蔻梢头行少年老成行敲到Shell提醒符下推行。
  • 鉴于历史由来,UNIX系统上有很各个Shell:

    • 1、sh(Bourne Shell):由SteveBourne开辟,种种UNIX系统都配有sh。
    • 2、csh(C Shell):由Bill Joy开荒,随BSD UNIX发表,它的流水生产线控制语句很象C语言,援救广大Bourne Shell把不扶植的机能:作业调控,命令历史,命令行编辑。
    • 3、ksh(Korn Shell):由大卫Korn开垦,向后特别sh的功能,并且加多了csh引进的新功效,是日前数不胜数UNIX系统规范配置的Shell,在这里些种类上/bin/sh往往是指向/bin/ksh的标识链接。
    • 4、tcsh(TENEX C Shell):是csh的巩固版本,引进了指令补全等功效,在FreeBSD、MacOS X等系统上代表了csh。
    • 5、bash(Bourne Again Shell):由GNU开荒的Shell,主要目的是与POSIX标保准持风姿浪漫致,同不时候全职对sh的协作,bash从csh和ksh借鉴了累累职能,是各样Linux发行版规范配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash和符号链接。固然那样,bash和sh仍有好多不相同的,一方面,bash扩充了一些限令和参数,另一面,bash并不完全和sh包容,有个别行为并不平等,所以bash须求效法sh的一举一动:当我们由此sh这些顺序名运营bash时,bash能够假装本人是sh,不认扩充的一声令下,并且作为与sh保持风流罗曼蒂克致。

        $ cat /etc/passwd
        root:x:0:0:root:/root:/bin/zsh
        daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
        bin:x:2:2:bin:/bin:/usr/sbin/nologin
        sys:x:3:3:sys:/dev:/usr/sbin/nologin
        sync:x:4:65534:sync:/bin:/bin/sync
      
  • 客商在命令行输入指令后,日常境况下Shell会fork并exec该命令,不过Shell的内建命令例外,实行内建命令相当于调用Shell进度中的叁个函数,并不创立新的进程。早前学过的cd、alias、umask、exit等一声令下便是内建命令,凡是用which命令查不到程序文件所在地点的一声令下都是内建命令,内建命令未有独自的man手册,要在man手册中查看内建命令,应该实行

      $ man bash-builtins
    
  • 如export、shift、if、eval、[、for、while等等。内建命令纵然不创立新的长河,但也许有Exit Status,平日也用0表示成功非零意味退步,尽管内建命令不创建新的进度,但实践达成后也可以有三个状态码,也足以用异样变量$?读出。

Author: Shixiang Wang

实施脚本

  • 编写多个简易的脚本test.sh:

      #! /bin/sh
      cd ..
      ls
    
  • Shell脚本中用#意味着注释,也就是C语言的//注释。但借使#位居第风流浪漫行开头,并且是#!(称为Shebang卡塔 尔(阿拉伯语:قطر‎则不相同,它代表该脚本使用前面钦赐的讲解器/bin/sh解释推行。假诺把那一个本子文件加上可进行权限然后施行:

      $ chmod a+x test.sh
      $ ./test.sh
    
  • Shell会fork贰个子历程并调用exec实践./test.sh其大器晚成顺序,exec系统调用应该把子进度的代码段替换来./test.sh先后的代码段,并从它的_start开头实行。但是test.sh是个公文文件,根本未曾代码段和_start函数,如何做吧?其实exec还大概有此外意气风发种体制,假使要推行的是叁个文本文件,並且第风度翩翩行用Shebang钦点掌握释器,则用解释程序的代码段替换当前历程,并且从解释器的_start始发推行,而以此文件文件被充当命令行参数字传送给解释器。因而,推行上述脚本也正是实施顺序

      $ /bin/sh ./test.sh
    
  • 以这种艺术推行无需test.sh文件可进行权限。

  • 后生可畏经将下令行下输入的命令用()括号括起来,那么也会fork出二个子Shell推行小括号中的命令,生机勃勃行中能够输入由支行;隔断的七个命令,比方:

      $ (cd ..; ls -l)
    
  • 和地点二种艺术奉行Shell脚本的功力是相仿的,cd ..命令退换的是子Shell的PWD,而不影响到交互作用式Shell。

      $ cd ..; ls -l
    
  • 则区别的意义,cd ..命令是直接在交互作用式Shell下进行的,改换交互作用式Shell的PWD,然则这种方法也就是那般进行Shell脚本:

      $ source ./test.sh
      或者
      $ . ./test.sh
    
  • source恐怕.命令是Shell的内建命令,这种方法也不会成立子Shell,而是径直在人机联作式Shell下逐行试行脚本中的命令。

[TOC]

着力语法

grep

变量

  • 遵照常规,Shell变量平日由字母加下划线开端,由自便长度的字母、数字、下划线组成。有二种档案的次序的Shell变量:
    • 1、际遇变量
      • 景况变量能够从父进度传给子进度,因些Shell进度的遭受变量可以从当下Shell进度传给fork出来的子过程。用printenv命令可以呈现当前Shell的意况变量。
    • 2、本地变量
      • 只存在于近年来Shell进程,用set指令能够展现当前Shell进程中定义的有所变量(包涵地面变量和际遇变量卡塔尔和函数。
  • 蒙受变量是其它进度都有的概念,而本土变量是Shell特有的定义。在Shell中,景况变量和本地变量的概念和用法相符。在Shell中定义或赋值二个变量:

      $ VARNAME=value
    
  • 小心等号两侧都不可能有空格,不然会被Shell解释成命令行参数。

  • 四个变量定义后仅存在于如今Shell进度,它是地点变量,用export命令能够把本地变量导出为蒙受变量,定义和导出蒙受变量常常能够一步成功:

      $ export VARNAME=value
    
  • 也足以分两步成功:

      $ VARNAME=value
      $ export VARNAME
    
  • 用unset命令能够删除已定义的意况变量或本地变量。

      $ unset VARNAME
    
  • 要是叁个变量叫做VAEnclaveNAME,用'VASportageNAME'能够代表它的值,在不引起歧义的境况下也能够用VACRUISERNAME表示它的值。通过以下的例子相比较这两种表示法的不等:

      $ echo $SHELL
    
  • 潜心,在概念变量时绝不"'",取变量值时要用。和C语言区别的是,Shell变量没有必要显明定义类型,事实上Shell变量的值都以字符串,比方我们定义VA奥迪Q5=45,其实VAEscort的值是字符串45而非整数。Shell变量无需先定义后接收,倘若叁个未有概念的变量取值,则值为空字符串。

grep的中坚用法

grep命令是支撑正则表达式的八个多用项文本寻找工具,常常格式为

grep 选项 模式 文件

选项 意义
-c 只输出匹配行的数量
-i 搜索时忽略大小写
-h 查询多文件时不显示文件名
-l 只列出符合匹配的文件名,而不列出具体的匹配行
-n 列出所有的匹配行,并显示行号
-s 不显示不存在或无匹配文本的错误信息
-v 显示不包含匹配文本的所有行
-w 匹配整词
-x 匹配正行
-r 递归搜索,不仅搜索当前目录,而且搜索子目录
-q 禁止输出任何结果,以退出状态表示搜索是否成功
-b 打印匹配行距文件头部的偏移量,以字节为单位
-o 与-b选项结合使用,打印匹配的词距文件头部的偏移量,以字节为单位
-E 支持扩展的正则表达式
-F 不支持正则表达式,按照字符串的字面意思进行匹配

grep命令的形式特别灵活,能够是字符串,也得以是变量,还足以是正则表明式。注意,无论格局是何种形式,只要格局中含有空格,就供给利用双引号将形式引起来。

文件名代换(Globbing卡塔 尔(英语:State of Qatar)

  • 这几个用于相称的字符称为通配符(Wildcard卡塔尔,如:*?[],具体如下:

    • *相称0个或几个随机字符
    • ?合营多个随便字符
    • [多少字符]极度方括号中随心所欲多少个字符的壹遍现身

        $ ls /dev/ttyS*
        $ ls ch0?.doc
        $ ls ch0[0-2].doc
        $ ls ch[012][0-9].doc
      
    • 只顾,Globbing所相称的文件名是由Shell张开的,也正是说在参数还未传给程序早前早就开展了,举个例子上述ls ch0[012].doc命令,倘诺当前目录下有ch00.doc和ch02.doc,则传给ls命令的参数实际上是那五个文本名,实际不是叁个相称字符串。

grep与正则表明式

  1. 相称行首,用元字符^
  1. 设置大小写,用-i

  2. 同盟重复字符,用., *

  3. 转义符,用

  4. POSIX字符类

    类名 意义
    [:upper:] 表示大写字母[A~Z]
    [:lower:] 表示小写字母[a~z]
    [:digit:] 表示阿拉伯数字[0~9]
    [:alnum:] 表示大小写字母和阿拉伯数字
    [:space:] 表示空格键和TAB键
    [:alpha:] 表示大小写字母
    [:cntrl:] 表示Ctrl
    [:graph:]或[:print:] 表示ASCII码
    [:xdigit:] 表示16进制数字[09AFa~f]
  5. 标准相配:用<>

  6. 或字符,grep需求丰裕-E选项能力扶助它,用|表示

一声令下代换

  • 由“`”反引号括起来的也是一条命令,Shell先实行该命令,然后将出口结果立即代换来当前命令行中。举个例子定义多个变量寄放date命令的输出:

      $ DATE=`date`
      $ echo $DATE
    
  • 一声令下代换也足以用$()表示:

      $ DATE=$(date)
    

grep命令族

grep: 标准grep命令

egrep: 扩充grep命令,帮忙大旨和进行正则表明式

fgrep: 飞速grep命令,不扶助正则表达式


算术代换

  • 应用$(()),用于算术总结,(())中的Shell变量取值将转换来整数,相通含义的$[]等价,例如:

      $ VAR=45
      $ echo $(($VAR+3))   等价于 echo $[VAR+3]或$[$VAR+3]
    
  • $(())中只好用+-*/和()运算符,况兼只好做整数运算。

  • $[base#n],个中base表示进制,n遵照base进制解释,后边再运算数,按十进制解释。

      $ echo $[2#10+11]
      $ echo $[8#10+11]
      $ echo $[16#10+11]
    

sed命令

sed是三个非交互作用式文本编辑器,它可对文本文件和正式输入进行编写制定,标准输入能够是源于键盘输入、文件重定向、字符串、变量,以致来自管道的公文。sed适用于以下三中场面:

  • 编排相对人机联作式文本编辑器来说太大的文件。
  • 编写制定命令太复杂,在交互作用式文本编辑器中难以输入的情景。
  • 对文本扫描二次,可是急需实施四个编辑函数的景色。

转义字符

  • 和C语言相符,在Shell中被用作转义字符,用于去除紧跟其后的单个字符的出格含义(回车除了这么些之外卡塔 尔(英语:State of Qatar),换句话说,紧跟其后的字符取字面值。举例:

      $ echo $SHELL
      /bin/bash
      $ echo $SHELL
      $SHELL
      $ echo \
      
    
  • 比方说成立四个文书名称为"$ $"的文书($间含有空格卡塔 尔(英语:State of Qatar),可以那样:

      $ touch $ $
    
  • 再有一个字符纵然不享有独特意义,可是要用它做文件名也很艰巨,正是-号。倘使要成立多个文件名以-号起头的文件,那样是不得法的:

      $ touch -hello
      touch:无效选项 -- e
      Try 'touch --help' for more information.
    
  • 即便加上转义也仍然报错:

      $ touch -hello
      touch:无效选项 -- e
      Try 'touch --help' for more information.
    
  • 因为各样UNIX命令都把-号开关的命令行参数作为命令的选项,而不会作为文件名。,如若非要管理以-号开端的文件名,大概有三种办法:

      $ touch ./-hello
      或者
      $ touch -- -hello
    

基本用法

sed只是对缓冲区炎黄始文件的别本实行编写制定,并不编辑原始文件。即使供给保留文件退换的内容,供给将出口重定向到另二个文书。

调用sed有三种办法,意气风发种为Shell命令行方式,其余两种是将sed指令写入脚本文件,然后施行该脚本文件。

  1. 在Shell命令行输入指令调用sed,格式为sed [选项] 'sed命令' 输入文件
  2. sed命令插入脚本文件后,然后通过sed命令调用它,格式为sed [选项] -f sed 脚本文件 输入文件
  3. sed命令插入脚本文件后,最常用的艺术是安装该脚本文件为能够施行,然后径直推行该脚本文件,格式为./sed脚本文件 输入文件

其三种方法脚本文件供给以sha-bang(#!)标识带头。无论哪一种形式,若无一点点名输入文件,sed将从标准输入接纳输入。常用选项有八个

选项 意义
-n 不打印所有的行到标准输出
-e 表示将下一个字符串解析为sed编辑命令,如果只传递一个,可以省略
-f 表示正在调用sed脚本文件

sed命令首要由确定地点文本行和sed编排命令两部分组成,有二种办法固定文本:

  • 使用行号,内定生机勃勃行,大概钦赐行号范围
  • 用正则表明式
选项 意义
x x为指定行号
x,y 指定从x到y的行号范围
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
/pattern/,x 从pattern匹配行到x号行
x,/pattern/ 上一条反过来
x,y! 查询不包括x和y行号的行

编写命令

选项 意义
p 打印匹配行
= 打印文件行号
a 在定位行号后追加文本信息
i 在定位行号之前插入文本信息
d 删除定位行
c 用新文本替代定位文本
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 将文本写入到一个文件
y 变换字符
q 第一个模式匹配后退出
l 显示与八进制ASCII码等价的控制字符
{} 在定位行执行的命令组
n 读取下一个输入行,用下一个命令处理新的行
h 将模式缓冲区的文本复制到保持缓冲区
H ...追加到保持缓冲区
x 互换模式缓冲区和保持缓冲区内容
g 将保持模式缓冲区的内容复制到模式缓冲区
G ....追加到模式缓冲区

单引号

  • 和C语言同,Shell脚本中的单引号和双引号相似是字符串的界定符(双引号下生龙活虎节介绍卡塔尔国,并不是字符的界定符。单引号用于保障引号内全部字符的字面值,即便引号内的和回车也不例外,可是字符串中无法冒出单引号。假如引号未有配对就输入回车,Shell会给出续行提醒符,必要客户把引号配上对。举例:

      $ echo '$SHELL'
      $SHELL
      $ echo 'ABC(回车)
      > DE'(再按一次回车结束命令)
      ABC
      DE
    

示例

测量试验文件内容:

    This is a Certificate Request file:

    It should be mailed to zawu@seu.edu.cn

    =====================================================
    Certificate Subject:

    /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus

    The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
    To install this user certificate, please save this e-mail message into the following file.

    /home/alloy/linuxshell/CH02/usercert.pem

双引号

  • 被双引号用括住的始末,将被视为单风姿罗曼蒂克的字串。它防止通配符扩张,但允许变量扩充。那点与单引号的管理方式差别

      $ DATE=$(date)
      $ echo "$DATE"
      $ echo '$DATE'
    
  • 再比如:

      $ VAR=200
      $ echo $VAR
      200
      $ echo '$VAR'
      $VAR
      $ echo "$VAR"
      200
    

sed -n: 不打字与印刷sed编辑目的的全体内容

wsx@wsx-ubuntu:~/桌面$ sed -n '1p' input
    This is a Certificate Request file:

wsx@wsx-ubuntu:~/桌面$ sed '1p' input
    This is a Certificate Request file:
    This is a Certificate Request file:

    It should be mailed to zawu@seu.edu.cn

    =====================================================
    Certificate Subject:

    /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus

    The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
    To install this user certificate, please save this e-mail message into the following file.

    /home/alloy/linuxshell/CH02/usercert.pem

动用sed命令打字与印刷范围行:

wsx@wsx-ubuntu:~/桌面$ sed -n '3,6p' input 
    It should be mailed to zawu@seu.edu.cn

    =====================================================
    Certificate Subject:

Shell脚本语法

sed -e: sed传递多少个编辑命令时行使

wsx@wsx-ubuntu:~/桌面$ sed -n '/Certificate/=' input 
1
6

wsx@wsx-ubuntu:~/桌面$ sed -n -e '/Certificate/p' input  -e '/Certificate/=' input
    This is a Certificate Request file:
1
    Certificate Subject:
6

原则测量试验

  • 命令test或[能够测量检验三个原则是还是不是创设,即使测量试验结果为真,则该命令的Exit Status为0,假若测量试验结果为假,则下令的Exit Status为1(注意与C语言的逻辑表示凑巧相反卡塔 尔(英语:State of Qatar)。举例测验三个数的大小关系:

      $ var=2
      $ test $var -gt 1
      $ echo $?
      0
      $ test $var -gt 3
      $ echo $?
      1
    
  • 固然看起来很古怪,但左边括号[真便是贰个下令的名字,传给命令的各参数之间应当用空格隔断,比如:$VA福睿斯、-gt、3、]和[命令的三个参数,它们中间必需用空格隔断。命令test或[的参数形式是形似的,只可是test命令无需]参数。以[指令为例,多如牛毛的测量检验命令如下表所示:

      [ -d DIR ]                 如果DIR存在并且是一个目录则为真
      [ -f FILE ]                如果FILE存在且是一个普通文件则为真
      [ -z STRING ]              如果STRING的长度为零则为真
      [ -n STRING ]              如果STRING的长度非零则为真
      [ STRING1 = STRING2 ]      如果两个字符串相同则为真
      [ STRING1 != STRING2 ]     如果两个字符串不相同则为真
      [ ARG1 OP ARG2 ]           ARG1和ARG2应该是整数或者取值为整数的变量,
                                 OP的值有:
                                      -eq     等于
                                      -ne     不等于
                                      -lt     小于
                                      -le     小于等于
                                      -gt     大于
                                      -ge     大于等于
    
  • 和C语言相仿,测量试验条件之间仍可以做与、或、非逻辑运算:

      [ ! EXPR ]           EXPR可以是上表中的任意一种测试条件, !表示"逻辑反(非)"
      [EXPR1 -a EXPR2 ]    EXPR1和EXPR2可以是上表中的任意一种测试条件,-a表示“逻辑与”
      [EXPR1 -o EXPR2 ]    EXPR1和EXPR2可以是上表中的任意一种测试条件,-o表示“逻辑或”
    
  • 例如:

      $ VAR=abc
      $ [ -d Desktop -a $VAR = 'abc' ]
      $ echo $?
      0
    
  • 只顾,假若上例中的$VA君越变量事先未有定义,则被Shell张开为空字符串,会引致测量试验条件的语法错误(打开为[ -d Desktop -a = 'abc']),作为后生可畏种好的Shell编制程序习贯,应该总是把变量取值放在双引号之中(展开为[ -d Desktop -a "" = 'abc'])

      $ unset VAR
      $ [ -d Desktop -a $VAR = 'abc' ]
      -bash: [: 参数太多
      $ [ -d Desktop -a "$VAR" = 'abc' ]
      $ echo $?
      1
    

sed -f:调用sed脚本文件时才起效果

wsx@wsx-ubuntu:~/桌面$ sed '/file:/aWe append a new line.' input 
    This is a Certificate Request file:
We append a new line.

    It should be mailed to zawu@seu.edu.cn

    =====================================================
    Certificate Subject:

    /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus

    The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
    To install this user certificate, please save this e-mail message into the following file.

    /home/alloy/linuxshell/CH02/usercert.pem

剧本用法:

#! /bin/sed -f 
/file:/a       #a表示在此处添加文本

# 添加文本
We append a new line.
We append a another line.

sed基本编辑命令能够放在单引号内,也可放在单引号外。

分支

  • if/then/elif/else/fi

    • 和C语言肖似,在Shell中用if、then、elif、else、fi这几条命令落成分支调控。这种流程序调控制语句本质上也是由若干条Shell命令组成的,举例早前讲过的

        if [ -f ~/.bashrc ]; then
            . ~/.bashrc
        fi
      
    • 其实是三条命令,if [ -f ~/.bashrc ]是第一条,then . ~/.bashrc是第二条,fi是第三条。假使两条命令写在同生龙活虎行则必要用;号隔断,生龙活虎行只写一条命令就无需写;号了,其它,then前面有换行,但那条命令没写完,Shell会自动续行,把下大器晚成行接在then前面当作一条命令管理。和[指令同样,要潜心命令和各参数之间必须用空格隔开。if命令的参数组成一条子命令,借使该子命令的Exit Status为0(表示真卡塔尔,则施行then前边的子命令上,假若Exit Status非0(表示假卡塔尔,则实践elif、else也许fi前面包车型地铁子命令。if后边的子命令平日是测量检验命令,但也得以是任何命令。Shell脚本未有{}括号,所以用fi表示if语句的甘休。见下例:

        #! /bin/sh
      
        if [ -f /bin/bash ]
        then
            echo "/bin/bash is a file"
        else
            echo "/bin/bash is NOT a file"
        fi
        if :; then echo "always true"; fi
      
    • ":"是贰个异样的通令,称为空命令,该命令不做别的事,但Exit Status总是真。别的,也得以试行/bin/true或/bin/false获得真或假的Exit Status。再看叁个例证:

        #! /bin/sh
      
        echo "Is it morning? Please answer yes or no."
        read YES_OR_NO
        if [ "$YES_OR_NO" = "yes" ]; then
            echo "Good morning!"
        elif [ "$YES_OR_NO" = "no" ]; then
            echo "Good afternoon!"
        else
            echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
            exit 1
        fi
        exit 0
      
    • 上例中的read命令的魔法是之类客户输入风度翩翩行字符串,将该字符串存到二个Shell变量中。

    • 此外,Shell还提供了&&和||语法,和C语言相同,具备Short-circuit天性,超级多Shell脚本喜欢写成这么:

        test "$(whoami)" != 'root' && (echo you are using a non-privileged account; exit 1)
      
    • &&也正是“if...then...”,而||相当于“if not...then...”。&&和||用于连接五个指令,而地点讲的-a和-o仅用于在测量试验表明式中接二连三八个测量试验条件,要留意它们的分裂,举个例子:

        test "$VAR" -gt 1 -a "$VAR" -lt 3
      
    • 和以下写法是等价的

        test "$VAR" -gt 1 && test "$VAR" -lt 3
      
  • case/esac

    • case命令可类比C语言的switch/case语句,esac代表case语句块的利落。C语言的case只可以合作整形或字符型常量表达式,而Shell脚本的case能够相称字符串和Wildcard,每一个相配分支能够有若干条命令,末尾必得以;;结束,实行时找到第四个极其的分支并实行相应的通令,然后径直跳到esac之后,无需像C语言相像用break跳出。

        #! /bin/sh
      
        echo "Is it morning? Please answer yes or no."
        read YES_OR_NO
        case "$YES_OR_NO" in
        yes|y|Yes|YES)
            echo "Good Morning!";;
        [nN]*)
            echo "Good Afternoon!";;
        *)
            echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
            exit 1;;
        esac
        exit 0
      
    • 应用case语句的例子能够在系统服务的脚本目录/etc/init.d中找到。那些目录下的本子多数具备这种样式(以/etc/init.d/nfs-kernel-server为例卡塔 尔(阿拉伯语:قطر‎:

        case "$1" in 
            start)
                ...
            ;;
            stop)
                ...
            ;;
            status)
                ...
            ;;
            reload | force-reload)
                ...
            ;;
            restart)
                ...
            ;;
            *)
                log_sucess_msg "Usage: nfs-kernel-server {start|stop|status|reload|force-reload|restart}"
                exit 1
            ;;
        esac
      
    • 伊始nfs-kernel-server服务的命令是

        $ sudo /etc/init.d/nfs-kernel-server start
      
    • $1是三个破例变量,在进行脚本时自动取值为率先个命令行参数,也正是start,所以进入start)分支推行相关的命令。同理,命令行参数钦点为stop、reload或restart能够进入其余分支试行结束服务、重新加载配置文件或再度起动服务的连带命令。

sed文本定位的风姿罗曼蒂克组例子

  1. 相称元字符,用转义符进行屏蔽

    wsx@wsx-ubuntu:~/桌面$ sed -n '/./p' input 
     It should be mailed to zawu@seu.edu.cn
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
     /home/alloy/linuxshell/CH02/usercert.pem
    
  2. 利用元字符举行匹配

    $在sed命令中意味着最后后生可畏行

    wsx@wsx-ubuntu:~/桌面$ sed -n '$p' input
     /home/alloy/linuxshell/CH02/usercert.pem
    
  3. !标志,打字与印刷不在2-10的行

    wsx@wsx-ubuntu:~/桌面$ sed -n '2,10!p' input 
     This is a Certificate Request file:
     To install this user certificate, please save this e-mail message into the following file.
    
     /home/alloy/linuxshell/CH02/usercert.pem
    
  4. 应用行号和主要性字相称限制行范围

    wsx@wsx-ubuntu:~/桌面$ sed -n '/seugrid/,$p' input 
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
    
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
    
     /home/alloy/linuxshell/CH02/usercert.pem
    

循环

  • for/do/done

    • Shell脚本的for循环结构和C语言十分不等同,它就像是于一些编制程序语言foreach循环。举例:

        #! /bin/sh
      
        for FRUIT in apple banana pear; do
            echo "I like $FRUIT"
        done
      
    • FRUIT是叁个循环变量,第二次循环$FRUIT的取值是apple,第三次取值是banana,第叁次取值是pear。再举例说,要将当前目录下的chap0、chap1、chap2等文件夹名改为chap0~、chap1~、chap2~等(按惯例,末尾有~字符的公文名代表不时文件卡塔尔国,这一个命令能够那样写:

        $ for FILENAME in chap?; do mv $FILENAME $FILENAME~; done
      
    • 也足以如此写:

        $ for FILENAME in `ls chap?`; do mv $FILENAME $FILENAME~; done
      
  • while/do/done

    • while的用法和C语言形似。举个例子二个验证码的台本:

        #! /bin/sh
      
        echo "Enter password:"
        read TRY
        while [ "$TRY" != "secret" ]; do
            echo "Sorry, try again"
            read TRY
        done
      
    • 上边的例证通过算术运算调控循环的次数:

        #! /bin/sh
      
        COUNTER=1
        while [ "$COUNTER" -lt 10 ]; do
            echo "Here we go again"
            COUNTER=$[$COUNTER+1]
        done
      
    • 另,Shell还或然有until循环,相符C语言的do...while。如有兴趣可在课后机动扩展学习。

  • break和continue

    • break[n]能够钦定跳出几层循环;continue跳过此次巡回,但不会跳出循环。
    • 即break跳出,continue跳过。
    • 练习:将地点表达密码的程序改进一下,即便客户输错伍回密码就报错退出。

sed基本编辑命令的生龙活虎组例子

  1. 插入文本:运营脚本,以输入文件名作为参数

    #!/bin/sed -f
    /file:/i             # i表示此处换行插入文本
    We insert a new line.
    
  2. 改良文件

    #!/bin/sed -f
    
    /file:/c             #c表示此处换行修改文本
    We modify this line      #修改文本内容
    
  3. 删除文本,符号是d,不带,与其它命令有所分歧,特别灵活。下边删除第风度翩翩行和末段黄金年代行。

    wsx@wsx-ubuntu:~/桌面$ sed '1d' input
    
     It should be mailed to zawu@seu.edu.cn
    
     =====================================================
     Certificate Subject:
    
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
    
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
    
     /home/alloy/linuxshell/CH02/usercert.pem
    wsx@wsx-ubuntu:~/桌面$ sed '$d' input
     This is a Certificate Request file:
    
     It should be mailed to zawu@seu.edu.cn
    
     =====================================================
     Certificate Subject:
    
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
    
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
    
  4. 退换文本,格式s/被替换的字符串/新字符串/[替换选项]

    选项 意义
    g 全局匹配替换(替换所有的)
    p 与-n选项结合,只打印替换行
    w 文件名 表示将输出定向到一个文件
    sx@wsx-ubuntu:~/桌面$ sed 's/Certificate/CERTIFICATE/' input
     This is a CERTIFICATE Request file:
    
     It should be mailed to zawu@seu.edu.cn
    
     =====================================================
     CERTIFICATE Subject:
    
     /O=Grid/OU=GlobusTest/OU=simpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
    
     The above string is known as your user certificate subject, and t uniquely identifies theis user. $88
     To install this user certificate, please save this e-mail message into the following file.
    
     /home/alloy/linuxshell/CH02/usercert.pem
    wsx@wsx-ubuntu:~/桌面$ sed -n 's/Certificate/CERTIFICATE/p' input
     This is a CERTIFICATE Request file:
     CERTIFICATE Subject:
    
  5. 写入到叁个新文件

    wsx@wsx-ubuntu:~/桌面$ sed -n 's/Certificate/CERTIFICATE/pg' input
     This is a CERTIFICATE Request file:
     CERTIFICATE Subject:
    wsx@wsx-ubuntu:~/桌面$ 
    wsx@wsx-ubuntu:~/桌面$ sed -n '1,5 w output' input
    wsx@wsx-ubuntu:~/桌面$ cat output 
     This is a Certificate Request file:
    
     It should be mailed to zawu@seu.edu.cn
    
     =====================================================
    
  6. 从文件中可读入文本,格式指定地址 r 文件名

  7. 分离命令:q

  8. 调换命令:sed命令的y表示字符转变(不等长时会报错)

    wsx@wsx-ubuntu:~/桌面$ sed 'y/fmj/FMJ/' input 
     This is a CertiFicate Request File:
    
     It should be Mailed to zawu@seu.edu.cn
    
     =====================================================
     CertiFicate SubJect:
    
     /O=Grid/OU=GlobusTest/OU=siMpleCA-seugridl.seu.edu.cn/OU=seu.edu.cn/CN=globus
    
     The above string is known as your user certiFicate subJect, and t uniquely identiFies theis user. $88
     To install this user certiFicate, please save this e-Mail Message into the Following File.
    
     /hoMe/alloy/linuxshell/CH02/usercert.peM
    
  9. 展现调控字符:调控字符正是非打字与印刷字符,如退格键、F1键等。使用sed l命令。

  10. 在命令行试行命令组,用{}符号,与-e选用功效看似。

    wsx@wsx-ubuntu:~/桌面$ sed -n '/Certificate/{p;=}' input
        This is a Certificate Request file:
    1
        Certificate Subject:
    6
    

岗位参数和特种变量

  • 有许多非正规变量是被Shell自动赋值的,大家早已蒙受了$?和$1。别的常用的职分参数和异样变量在这里间总计一下:

      $0           相当于C语言main函数的argv[0]
      $1、$2...    这些称为位置参数(Positional Parameter),相当于C语言main函数的argv[1]、argv[2]...
      $#           相当于C语言main函数的argc - 1,注意这里的#后面不表示注释
      $@           表示参数"$1" "$2" ...,例如可以用在for循环中的in后面 
      $*           表示参数"$1" "$2" ...,同上
      $?           上一条命令的Exit Status
      $$           当前进程号
    
  • 职位参数能够用shift命令左移。举例shift 3表示原来的$4今后改成$1,原来的$5今后改为$2等等,原本的$1、$2、$3废弃,$0不移动。不带参数的shift命令相当于shift 1。举例:

      #! /bin/sh
    
      echo "The program $0 is now running"
      echo "The first parameter is $1"
      echo "The second parameter is $2"
      echo "The parameter list is $@"
      shift
      echo "The first parameter is $1"
      echo "The second parameter is $2"
      echo "The parameter list is $@"
    

awk编程

awk是多少人长辈开垦的编制程序语言,awk是三人创小编的首字母。基本语言与C雷同。

一时一刻,使用的是gawk,Linux系统中/bin目录下有awkgawk三个指令,前面一个实际上是后人的链接。利用gawk言语能够兑现数量检索、抽出文件中的数据、成立管道流命令等功能。

作者们能够轻巧地将awk编制程序模型分位四个等第:

  • 读输入文件试行的实行代码段(由BEGIN关键字标记卡塔 尔(阿拉伯语:قطر‎
  • 读取输入文件时实行代码段
  • 读输入文件从今现在的试行代码段(由END关键字标记卡塔尔

调用方法分为二种:Sehll命令市价势;脚本实践。

输入输出

  • echo

    • 来得文本行或变量,可能把字符串输入到文件。

        echo [option] string
        -e 解析转义字符
        -n 不回车换行。默认情况echo回显的内容后面跟一个回车换行。
        echo "hellonn"
        echo -e "hellonn"
        echo "hello"
        echo -n "hello"
      
  • 管道

    • 能够通过 | 把叁个指令的出口传递给另二个指令做输入。

        cat myfile | more
        ls -l | grep "myfile"
        df -k | awk '{print $1}' | grep -v "文件系统"
        df -k 查看磁盘空间,找到第一列,去除“文件系统”,并输出
      
  • tee

    • tee命令把结果输出到正规输出,另三个副本输出到对应文件。

        df -k | awk '{print $1}' | grep -v "文件系统" | tee a.txt
      
    • tee -a a.txt表示追加操作。

        df -k | awk '{print $1}' | grep -v "文件系统" | tee -a a.txt        
      
  • 文本重定向

      cmd > file              把标准输出重定向到新文件中
      cmd >> file             追加
      cmd > file2 2>&1        标准出错也重定向到1所指向的file里
      cmd >> file2 2>&1       
      cmd < file1 > file2     输入输出都定向到文件里
      cmd < &fd               把文件描述符fd作为标准输入
      cmd > &fd               把文件描述符fd作为标准输出
      cmd < &-                关闭标准输入
    

awk方式相称

别的awk语句都由格局和动作结合。方式是风度翩翩组用于测验输入行是否须求实施动作的规行矩步,动作是带有语句、函数和表明式的实行进程。awk支撑具有的正则表明式元字符,以致?+四个扩展元字符。

wsx@wsx-ubuntu:~/桌面$ awk '/^$/{print "This is a blank line."}' input
This is a blank line.
This is a blank line.
This is a blank line.
This is a blank line.
This is a blank line.

单引号中间为awk命令,由两有的构成,以“/”符号分隔,^$是形式,花括号部分是动作。该awk表示只要读入的输入文件是空行,就打字与印刷前边的字符串This is a blank line

利用脚本(将指令输入三个文件中):

wsx@wsx-ubuntu:~/桌面$ awk -f src.awk input
This is a blank line.
This is a blank line.
This is a blank line.
This is a blank line.
This is a blank line.

剧情不仅仅这几个,大家先谈谈别的概念。

函数

  • 和C语言相同,Shell中也是有函数的定义,不过函数定义中未有重回值也不曾参数列表。举例:

      #/bin/sh
    
      foo(){ echo "Function foo is called"; }
    
      echo "-=start=-"
      foo
      echo "-=end=-"
    
  • 注意函数体的左花括号{和前面包车型客车下令之间必需有空格或换行,借使将最后一条命令和右花括号}写在风流倜傥行,命令末尾必得有总局;但,不提出将函数定义的写在豆蔻梢头行上,不平价脚本阅读。

  • 在定义foo()函数时并不推行函数体中的命令,就象定义变量相似,只是给foo那么些名一个定义,到后边调用foo函数的时候(注意Shell中的函数调用不写括号卡塔尔才实行函数体中的命令。Shell脚本中的函数必得先定义后调用,通常把函数定义语句写在本子的近些日子,把函数调用和其他命令写在剧本的尾声(相像C语言中的main函数,那才是任何脚本实际初始施行命令的地点卡塔尔国。
  • Shell函数未有参数列表并不表示无法传参数,事实上,函数就象是Mini脚本,调用函数时得以传大六个参数,在函数内部雷同是用$0、$1、$2等变量来领取参数,函数中之处参数也正是函数的某些变量,改换这一个变量并不会耳闻则诵外面包车型大巴$0、$1、$2等变量。函数中得以用return命令归来,就算return后边跟一个数字则意味函数的Exit Status。
  • 下边这一个本子能够一次创制多少个目录,各目录名通过命令行参数字传送入,脚本每种测量检验各目录是或不是留存,假若目录不设有,首先打字与印刷音信然后试着创设该目录。

      #! /bin/sh
      is_directory(){
          DIR_ANME=$1
          if [ ! -d $DIR_ANME ]
              return 1
          else
              return 0
          fi
      }
    
      for DIR in "$@"; do
          if is_directory "$DIR"
          then : 
          else
              echo "$DIR doesn't exist, Creating it now..."
              mkdir $DIR > /dev/null 2>&1
              if [ $? -ne 0 ]; then
                  echo "Cannot create directory $DIR"
                  exit 1
              fi
          fi
      done
    
  • 注意:is_directory返回0表示真,返回1表示假

笔录和域

awk觉得输入文件是结构化的,awk将各样输入文件行定义为记录,行中的每贰个字符串定义为域,域之间用空格、TAB键或别的标记进行分隔,分隔域的符号就叫分隔符。(那个结构化概念需求掌握,超级多指令和编制程序中都有涉嫌卡塔尔国

wsx@wsx-ubuntu:~/桌面$ awk '{print $2,$1,$4,$3}' sturecord 
Hao Li 025------------ njue
Ju Zhang 025---------- nju
Bin Wang 025------ seu
wsx@wsx-ubuntu:~/桌面$ awk '{print $0}' sturecord 
Li Hao  njue 025------------ 
Zhang Ju    nju 025---------- 
Wang Bin    seu 025------

可以由此对域的操作对文本举行重新排列,也足以用print $0输入全体域。

wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {one=1;two=2}{print $(one+two)}' sturecord 
njue
nju
seu

BEGIN字段中定义onetwo七个变量并赋值。

-F慎选拔来改换分隔符,举个例子只以't'为分隔符。

wsx@wsx-ubuntu:~/桌面$ awk -F't' '{print $2}' sturecord 
025------------ 
025---------- 
025------

注意-F-f的区别。

awk还提供了另黄金时代种更利于的艺术纠正分隔符。

wsx@wsx-ubuntu:~/桌面$ cat sturecord 
Li Hao,njue,025------------ 
Zhang Ju,nju,025---------- 
Wang Bin,seu,025------
wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=","}{print $1, $3}' sturecord 
Li Hao 025------------ 
Zhang Ju 025---------- 
Wang Bin 025------

Shell脚本调节和测量试验方法

  • Shell提供了有个别用以调节和测量试验脚本的选项,如:

      -n      读一遍脚本中的命令但不执行,用于检查脚本中的语法错误。
      -v      一边执行脚本, 一边将执行过的脚本命令打印到标准错误输出。
      -x      提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。
    
  • 这个选取有三种多如牛毛的行使方法:

  • 1、在命令行提供参数。如:

      $ sh -x ./script.sh
    
  • 2、在本子开关提供参数。如:

      #! /bin/sh -x
    
  • 3、在本子中用set命令运营或剥夺参数。如:

      #! /bin/sh
    
      if [ -z "$1" ]; then
          set -x
          echo "ERROR: Insufficient Args."
          exit 1
          set +x
      fi
    
  • set -x和set +x分别表示启用或剥夺-x参数,那样能够只对台本中的某后生可畏段进展跟踪调节和测量检验。

事关和布尔运算符

awk定义了生机勃勃组关系运算符用于awk方式相配。如下表

运算符 意义
< 小于
> 大于
<= 小于或等于
>= 大于或等于
== 等于
!= 不等于
~ 匹配正则表达式
!~ 不匹配正则表达式

用/etc/passwd文件做个例证

# 第1域匹配root
wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} $1~/root/' /etc/passwd
# 全部域匹配root
root:x:0:0:root:/root:/bin/bash
wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} $0~/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 全部域不匹配nologin
wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} $0!~/nologin/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:4:65534:sync:/bin:/bin/sync
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin

awk条件语句与C相同,有if语句,if/else语句以至if/else else语句三种。

上面是援助的布尔运算符

运算符 意义
|| 逻辑或
&& 逻辑与
! 逻辑非
# 多条件精确匹配
wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} {if($3==10||$4==10) print $0}' /etc/passwd
# 多条件模糊匹配
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
wsx@wsx-ubuntu:~/桌面$ awk 'BEGIN {FS=":"} {if($3~10||$4~10) print $0}' /etc/passwd
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin/false
whoopsie:x:109:116::/nonexistent:/bin/false
avahi-autoipd:x:110:119:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
wsx:x:1000:1000:wsx,,,:/home/wsx:/bin/bash
nx:x:123:1001::/var/NX/nx:/etc/NX/nxserver

正则表达式

  • 早前我们用grep在三个文本中搜索含有有些字符串的行,比方在头文件中搜索叁个宏定义。其实grep还足以搜索切合有些模式(Pattern卡塔 尔(阿拉伯语:قطر‎的生机勃勃类字符串。举例寻觅全体符合xxx@xxx.xxx情势的字符串(也等于email地址卡塔尔国,必要x字符能够是字母、数字、下划线、小数点或减号,email地址的每大器晚成有个别能够有二个或四个x字符,譬如abc.d@ef.com、1_2@987-6.54,当然适合那些方式的不全部都以合法的email地址,但起码能够做贰次始发筛选,筛掉a.b、c@d等自然不是email地址的字符串。再举例说,找寻装有相符yyy-yyy-yyy-yyy方式的字符串(也正是IP地址卡塔尔,必要y是0-9的数字,IP地址的每黄金时代部分能够有1-3个y字符。
  • 如果用grep查找一个格局,怎么着表示这一个形式,这生机勃勃类字符串,并不是一定的字符串呢?从那八个简易的例子可以看出,要代表一个方式最少应当包括以下音信:
  • 字符类(Character Class卡塔 尔(阿拉伯语:قطر‎:如上例的x和y,它们在械中表示二个字符,不过取值范围是风姿浪漫类字符中的率性二个。
  • 多少节制符(Quantifier卡塔 尔(阿拉伯语:قطر‎:邮件地址的每三个某些可以有一个或多个x字符,IP地址的每风流倜傥局地能够有1-3个y字符。
  • 种种字符类以至经常见到字符之间的岗位关系:比如邮件地址分三片段,用日常字符@和.隔断,IP地址分四部分,用.隔绝,每生龙活虎有个别都足以字符类和数码限定符描述。为了表示地方关系,还会有地点节制符(Anchor卡塔 尔(英语:State of Qatar)的定义,将要底下介绍。
  • 规定部分特有语法表示字符类、数量节制符和地点关系,然后用那个优质语法和日常性字符一同表示二个情势,那就是正则表达式(Regular Expression卡塔 尔(英语:State of Qatar)。比如email地址的正则说明式可以写成[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+.[a-zA-Z0-9_.-]+,IP地址的正则表明式可以写成[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}。下意气风发节介绍正则表达式的语法,大家先看看正则表达式在grep中怎么用。举例有这么二个文书testfile:

      192.168.1.1
      1234.234.04.5678
      123.4234.045.678
      abcde
    
      $ egrep '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' testfile
      192.168.1.1
      1234.234.04.5678
    
  • egrep也便是grep -E,表示选取Extended正则说明式语法。grep的正则表明式有Basic和Extended三种标准,它们之间的界别下风姿浪漫节再解释。其它还也许有fgrep命令,也正是grep -F,表示只寻觅一定字符而不找出正则表达式格局,不会按正则表明式的语法解释前边的参数。

  • 注意正则表明式参数用单引号括起来了,因为正则表明式中用到的浩大特殊字符在Shell中也可能有独特意义(比方卡塔 尔(英语:State of Qatar),唯有用单引号括起来本事确定保证那个字符未有丝毫改动地传给grep命令,而不会被Shell解释掉。
  • 192.168.1.1切合上述方式,由五个.隔开分离的四段组成,每段都以1到3个数字,所以那生机勃勃行被寻觅来了,可为啥1234.234.04.5678也被寻找来了吧?因为grep找的是含有某一情势的行,那意气风发行富含叁个顺应形式的字符串234.234.04.567。相反,123.4234.045.678那生龙活虎行不包罗相符情势的字符串,所以不会被寻觅来。
  • grep是黄金年代种检索过滤工具,正则表明式在grep中用来寻找切合情势的字符串。其实正则表明还也有一个注重的行使是印证客商输入是还是不是合法,比方顾客通过网页表单提交自个儿的email地址,就必要用程序验证一下是否官方的email地址,那几个专门的职业能够在网页的javascript中做,也能够在网址后台程序中做,举例PHP、Perl、Python、Ruby、Java或C,全体那个语言都协助正则表明式,可以说,近日不扶助正则表明式的编制程序语言实在少见。除了编制程序语言之外,超多UNIX命令和工具也都支持正则表明式,举例grep、vi、sed、awk、emacs等等。“正则表达式”就疑似“变量”雷同,它是贰个广大的概念,实际不是某大器晚成种工具或编制程序语言的风味。

表达式

四个awk表明式能够由数值、字符常量、变量、操作符、函数和正则表明式自由组合而成。

运算符 意义
+
-
*
/
%
^或** 乘方
++x 在返回x之前,x变量加1
x++ 在返回x之后,x变量加1
wsx@wsx-ubuntu:~/桌面$ awk '/^$/{print x+=1}' input
1
2
3
4
5

中央语法

  • 咱俩知道C的变量和Shell脚本变量的定义和平运动用情势特别不一样等,表达本事也差别等,C的变量有各体系型,而Shell脚本变量都以字符串。雷同道理,各样工具和编制程序语言研讨所使用的正则表明式标准的语法并不雷同,说明本事也各不雷同,有的正则表明式标准引入超级多扩展,能发布更目眩神摇的情势,但种种正则表明式规范的基本概念都是想通的。本节介绍egrep(1卡塔 尔(英语:State of Qatar)所选拔的正则表明式,它概况上符合POSIX正则表明式标准,详见regex(7)(看这一个man page对您的俄语相对是很好的精雕细琢卡塔尔国。希望读者仿照上后生可畏节的事例,生龙活虎边上学语法,后生可畏边用egrep命令加强验。
  • 字符类
    • .协作任性叁个字符,abc.能够相配abcd、abc9等。
    • []匹配括号中的任性二个字符,[abc]d能够相配ad、bd或cd。
    • -在[]括号内代表字符范围,[0-9a-fA-F]能够包容壹个人十三进制数字。
    • ^位于[]括号内的发端,相配括号中的字符之外的随机叁个字符,[^xy]匹配xy之外的任一字符,由此[^xy]1能够相称a1、b1但不相配x1、y1。
    • [[:xxx:]]grep工具预订义的有的命名字符类,[[:alpha:]]相配二个假名,[[:digit:]]非常二个数字。
  • 数量约束符

    • ?紧跟在它前边的单元相称零次或二遍,[0-9]?.[0-9]相称0.0、2.3、.5等,由于.在正则表达式中是三个特殊字符,所以要求用转义一下,取字面值。
    • +紧跟在它前面的单元应同盟二遍或频仍,[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+.[a-zA-Z0-9_.-]+匹配email地址。
    • *紧跟在它前面的单元应十一分零次或频仍,[0-9][0-9]*相配最少二个数字,等价于[0-9]+[a-zA-Z_]+[a-zA-Z_0-9]*相称C语言的标记符。
    • {N}紧跟在它前边的单元应准确相配N次,[1-9][0-9]{2}匹配从100到999的整数。
    • {N,}紧跟在它前边的单元应异常最少N次,[1-9][0-9]{2,}协作肆人以上(含四位卡塔 尔(阿拉伯语:قطر‎的整数。
    • {,M}紧跟在它前边的单元应卓殊最多M次,[0-9]{,1}相当于[0-9]?
    • {N,M}紧跟在它后面包车型地铁单元应同盟最少次,最多M次,[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}匹配IP地址。
    • 再也注意:grep找的是包罗某一形式的行,并非全然相配某一情势的行
    • 举例说犹如下文本:

        aaabc
        aad
        efg
      
    • 查找a*其一方式的结果,会意识,三行都被找了出来。

        $ egrep 'a*' testfile
        aaabc
        aad
        efg
      
    • a相称0个或多少个a,而第三行满含0个a,所以也带有了这一方式。单独用a那样的正则表达式做查找没什么意义,平常是把a*用作正则表明式的豆蔻梢头有的来用。

  • 地点限制符

    • ^相称行首的义务,^Content极其位于后生可畏行起先的Content。
    • $合营行末的职位,;$合作位于生龙活虎行结尾的;号,^$相配空行。
    • <相配单词按钮之处,<th匹配... this,但不相称ethernet、tenth。
    • >万分单词结尾的岗位,p>相称leap ...,但不相配parent、sleepy。
    • b协作单词开关或最后的岗位,batb相配... at ...,但不相称cat、atexit、batch。
    • B相称非单词起头和最后的职位,BatB相称battery,但不相称... attend、hat ...
    • 职位限制符能够辅助grep改进确地寻找。
    • 例如说上风流洒脱节我们用[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}检索IP地址,找到这两行

        192.168.1.1
        1234.234.04.5678
      
    • 如果用^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$查究,就可以1234.234.04.5678那黄金年代行过滤掉了。

  • 别的特殊字符

    • 转义字符,普通字符转义为特殊字符,特殊字符转义为日常字符。普通字符<写成<表示单词起初的任务,特殊字符.写成.以至写成就作为普通字符来协作。
    • ()将正则表明式的风流倜傥部分括起来组成叁个单元,能够对全体单元使用数据限制符。([0-9]{1,3}.){3}[0-9]{1,3}匹配IP地址
    • |老是七个子表达式,表示或的关联。n(o|either)匹配no或neither

系统变量

awk定义了过多内建变量用于安装条件消息,大家称为系统变量。分为三种:风姿浪漫种用于转移awk的暗中同意值,举例域分隔符;第两种用于定义系统值,在拍卖文件时得以读取这几个系统值。

变量名 意义
$n 当前记录的第n个域,域用FS分隔
$0 记录的所有域
ARGC 命令行参数的数量
ARGIND 命令行中当前文件的位置(从0开始标号)
ARGV 命令行参数的数组
CONVFMT 数字转换格式
ENVIRON 环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表,以空格键分隔
FILENAME 当前文件名
FNR 浏览文件的记录数
FS 字段分隔符,默认是空格键
IGNORECASE 布尔变量,如果为真,则进行忽略大小写的匹配
NF 当前记录中的域数量
NR 当前记录数
OFMT 数字的输出格式
OFS 输出域分隔符,默认是空格键
ORS 输出记录分隔符,默认是换行符
RLENGTH 由match函数所匹配的字符串长度
RS 记录分隔符,默认是空格键
RSTART 由match函数所匹配的字符串的第1个位置
SUBSEP 数组下标分隔符,默认值是34

Basic正则和Extended正则差距

  • 如上介绍的是grep正则表达式的Extended规范,Basic标准也是有那个语法,只是字符?+{}|()应表明为更仆难数字符,要表示上述特殊意义则供给加转义。如若用grep而不是egrep,何况不加-E参数,则应依照Basic标准来写正则表明式。

格式化输出

awk借鉴C语言的语法,定义了printf出口语句。基本语法如下:

printf(格式控制符, 参数)

格式调整符分为修饰符和格式符三种,如下:

修饰符 意义
- 左对齐
width 域的步长
.prec 小数点右边的位数
运算符 意义
%c ASCII字符
%d 整型数
%e 浮点数,科学计数法
%f 浮点数
%o 八进制数
%s 字符串
%x 十六进制数

grep

  • 1、作用
    • Linux系统中grep命令是意气风发种强盛的公文寻觅工具,它能应用正则表明式寻觅文件,并把相配的行打字与印刷出来。grep全称是Global Regular Expression Print,表示全局正则表明式版本,它的应用权力是具有客商。
    • grep家族包括grep、egrep和fgrep。egrep和fgrep的授命只跟grep有超小分化。egrep是grep的恢弘,扶助越来越多的re元字符,fgrep就是fixed grep和fast grep,它们把装有的字母都充任单词,也正是说,正则表明式中的元字符表示回其自己的字面意义,不再新鲜。linux使用GNU版本的grep。它效果与利益越来越强,能够因此-G、-E、-F命令选项来使用egrep和fgerp的效率。
  • 2、格式及首要参数
    • grep [option]
    • 首要参数:grep -help可查阅
      • -c:只输出相配行的计数。
      • -i:不区分轻重缓急写。
      • -h:查询多文本时不展现文件名。
      • -l:查询多文本时只输出包涵相配字符的文件名。
      • -n:呈现相称行及行号。
      • -s:不显得不设有或无匹配文本的错误新闻。
      • -v:展现不包蕴相配文本的富有行。
      • --color=auto:能够将找到的第生龙活虎词部分加上颜色的展现。
    • pattern正则表明式首要参数:
      • :忽视正则表明式中特殊字符的原本含义。
      • ^:相称正则表明式的始发行
      • $:相称正则表明式的完成行
      • <:从相配正则表明式的行开首
      • >:到极度正则表明式的行终止
      • []:单个字符,如[A]即A适合供给
      • [ - ]:范围,如[A-Z],即A、B、C一向到Z都适合供给。
      • .:全数的单个字符。
      • *:全数字符,长度可感到0。
  • 3、grep命令使用轻便实例

      $ grep 'test' d*            显示所有以d开头的文件中包含test的行。
    

内置字符串函数

awk提供了强盛的停放字符串函数,用于贯彻公文的字符串替换、查找以致分隔等功效,下表列出:

函数名 意义
gsub(r,s) 在输入文件中用s替换r
gsub(r,s,t) 在t中用s替换r
index(s,t) 返回s中字符串第一个t的位置
length(s) 返回s的长度
match(s,t) 测试s是否包含匹配t的字符串
split(r,s,t) 在t上将r分为序列s
sub(r,s,t) 将t中第1次出现的r替换为s
substr(r,s) 返回字符串r中从s开始的后缀部分
substr(r,s,t) 返回字符串r中从s开始长度为t的后缀部分

find

  • 是因为find具备强有力的职能,所以它的选项也相当多,当中山高校部分取舍都值得我们花时间来询问一下。固然系统中包括网络文件系统(NFS卡塔 尔(阿拉伯语:قطر‎,find命令在该文件系统中后生可畏致有效,只要你具备相应的权限。
  • 在运维贰个不胜消耗电源的find命令时,很三个人都支持于把它身处后台试行,因为遍历贰个大的文件系统也许会花销十分短的年月(这里是指30G字节以上的文件系统卡塔尔国。
  • 大器晚成、find命令格式

    • 1、find命令的平时情势为

      find pathname -options [-print -exec -ok ...]

    • 2、find命令的参数

      • pathname:find命令所查找的目录路径。比方用.来表示当前目录,用/来表示系统根目录,递归查找。
      • -print:find命令将非凡的文本输出到典型输出。
      • -exec:find命令对天造地设的文本施行该参数所付出的shell命令。相应命令的款式为'command' {} ;,注意{}内部无空格,和;之间含有三个空格分隔符。
      • -ok:和-exec的法力相通,只但是以黄金年代种特别安全的情势来进行该参数所提交的shell命令,在实践每三个指令在此以前,都会付出提示,让顾客来规定是否实施。
    • 3、find命令选项
      • -name:根据文件名查找文件。
      • -perm:依据文件权限来查找文件。
      • -prune:使用那生机勃勃选项能够使find命令不在当前点名的目录中搜索,借使同一时候选用-depth选项,那么-prune将被find命令忽视。
      • -user:根据文件属主来查找文件。
      • -group:依据文件所属的组来查找文件。
      • -mtime -n +n:依照文件的退换时间来查找文件,-n代表文件改过时间距今后n天以内,+n表示文件改过时间间距今后n天从前。find命令还应该有-atime和-ctime选项,但它们都有-mtime选项。
      • -nogroup:查找无有效属组的文书,即该公文所属的组在/etc/groups中一纸空文。
      • -nouser:查找无有效属主的文书,即该公文的属主在/etc/passwd中一纸空文。
      • newer file1 ! file2:查找改过时间比文件file1新但比文件file2旧的文本。
      • -type:查找某一门类的文书,诸如:
        • b:块设备文件
        • d:目录
        • c:字符设备文件
        • p:管道文件
        • l:符号链接文件
        • f:普通文书
      • -size n:[c]查找文件长度为n块的文书,带有c时表示文件长度以字节计。
      • -depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
      • fstype:查找位于某大器晚成品类文件系统中的文件,那些文件系统类型日常能够在配置文件/etc/fstab中找到,该配置文件中富含了本系统中关于文件系统的音讯。
      • mount 在查找文件时不超过文件系统mount点。
      • follow 借使find命令遭逢符号链接文件,就追踪至链接所针没错文件。
    • 除此以外,上面三个的界别:
      • -amin n 查找系统中最终n分钟访谈的文本
      • -atime n 查找系统中最后n*24小时访问的公文
      • -cmin n 查找系统中最后n分钟被改换文件状态的文本
      • -ctime n 查找系统中最后n*24小时被改换文件状态的公文
      • -mmin n 查找系统中最后n分钟被改善文件数量的文本
      • -mtime n 查找系统中最后n*24钟头被改善文件数量的公文
    • 4、使用exec或ok来执行shell命令

      • 利用find时,只要把想要的操作写在四个文书里,就足以用exec来合营find查找,很便利的。
      • 在有一些操作系统中只同意-exec选项诸如ls或ls -l那样的吩咐。大好些个客商使用那风姿洒脱选项是为着探究旧文件并剔除它们。建议在真的举办rm命令删除文件在此之前,最棒先用ls命令看一下,确认它们是负有删除文件。
      • exec选项前面跟随着所要实施的命令或脚本,然后是生龙活虎对儿{},叁个空格和贰个,最终是叁个分行。为了使用exec选项,必定要同有时候选拔print选项。如若证实一下find命令,会发觉该命令只输出从脚下路径起的相对路线及文件名。
      • 例如:为了用ls -l命令列出所相称的文书,可以把ls -l命令放在find命令的-exec选项中

          $ find . -type f -exec ls -l {} ;
        
      • 地点的例子中,find命令相称到了当前目录下的全部普通文书,并在-exec选项中采取ls -l命令将它们列出。

      • 在/logs目录中找找改进时间在5日早前的公文并剔除它们:

          $ find logs -type f -mtime +5 -exec rm {} ;
        
      • 纪事:在shell中用别的方法删除文件从前,应超越查占星应的文书,必须求小心!当使用诸如mv或rm命令时,能够动用-exec选项的安全格局。它就要对每种相称到的文件操作在此之前提示您。

      • 在上边包车型大巴事例中,find命令在当前目录中探求全体文件名以.LOG结尾、修改时间在5日以上的文本,并剔除它们,只然则在剔除以前先提交指示。

          $ find . -name "*.conf" -mtime +5 -ok rm {} ;
          < rm ... ./conf/httpd.conf > ? n
        
      • 按y键删除文件,按n键不删除。

      • 此外款式的下令都能够在-exec选项中动用。
      • 在底下的事例中大家运用grep命令。find命令首先相称全体文件名字为"passwd*"的文本,举个例子passwd、passwd.old、passed.bak,然后实施grep命令看看在此些文件中是还是不是存在二个itcast客户。

          $ find /etc -name "passwd*" -exec grep "root" {} ; 
          root:x:0:0:root:/root:/bin/zsh
        
  • 二、find使用例子

      find ./ -name *.mp3
    
      find ./ -type f/d/p/c/b/s/l
    
      find ./ -size +3M -size -7M             默认单位:512B  0.5k  一个扇区大小 
    
      find ./ -size +47k -size -89k
    
      find ./ -maxdepth 2 -type d
    
      find ./ -maxdepth 1 -name "*.sh" -exec rm -r {} ;
    
      find ./ -maxdepth 1 -name "*.sh" -ok rm -r {} ;
    
      find ./ -maxdepth 1 -type f -print0 | xargs -0 ls -lh
    
      find ./ -name "*.gz" -mtime -5 -exec ls -lh {} /;
    

向awk脚本传递参数

awk脚本内的变量能够在指令行中进行赋值,完成向awk脚本传递参数,变量赋值放在脚本之后、输入文件早先,格式为:

awk脚本 parameter=value 输入文件

sed

  • sed意为流编辑器(Stream Editor卡塔 尔(英语:State of Qatar),在Shell脚本和Makefile中作为过滤器使用十一分普通,也便是把前面一个顺序的出口引进sed的输入,经过大器晚成密密层层编写制定命令转变为另生机勃勃种格式输出。sed和vi都出自开始时代UNIX的ed工具,所以广大sed命令和vi的末行命令是相像的。
  • sed命令行的为主格式为:

      sed option 'script' file1 file2 ...
      sed option -f scriptfile file1 file2 ...
    
  • 选择含义:

        -n, --quiet, --silent
                       静默输出,默认情况下,sed程序在所有脚本指令执行完毕后,
                       将自动打印模式空间中的内容,这些选项可以屏蔽自动打印。
    
        -e 脚本, --expression=脚本
                       允许多个脚本指令被执行。
    
        -f 脚本文件, --file=脚本文件
                       从文件中读取脚本指令,对编写自动脚本程序来说很棒!
    
        --follow-symlinks
                       直接修改文件时跟随软链接
    
        -i[SUFFIX], --in-place[=SUFFIX]
                       直接修改源文件,经过脚本指令处理后的内容将被输出至源文件
                      (源文件被修改)慎用!
    
        -l N, --line-length=N
                       该选项指定l指令可能输出的行长度,l指令用于输出非打印字符。
    
        --posix
                       禁用GNU sed扩展功能。
    
        -r, --regexp-extended
                       在脚本指令中使用扩展正则表达式
    
        -s, --separate
                       默认情况下,sed将把命令行指定的多个文件名作为一个长的连续的输入流。
                       而GNU sed则允许把他们当作单独的文件,这样如正则表达式则不进行跨文件匹配。
    
        -u, --unbuffered
                       从输入文件读取最少的数据,更频繁的刷新输出
    
        -z, --null-data
                       separate lines by NUL characters
            --help     显示帮助文档
            --version  显示sed版本。
    
        - 如果没有 -e, --expression, -f 或 --file 选项,那么第一个非选项参数被视为
          sed脚本。其他非选项参数被视为输入文件,如果没有输入文件,那么程序将从标准
          输入读取数据。
    
  • 如上仅是sed程序自个儿的选项意义表明,至于具体的剧本指令(即对文件内容做的操作卡塔 尔(英语:State of Qatar)前面大家会详细描述,这里大致介绍多少个剧本指令操作作为sed程序的例证。

      a,  append          追加
      i,  insert          插入
      d,  delete          删除
      s,  substitution    替换
    
  • 如:$ sed "2a test" ./testfile在输出testfile内容的第二行后增添"test"。

      $ sed "2,5d" testfile
    
  • sed处理的公文既能由职业输入重定向得到,也能够当命令行参数字传送入,命令行参数能够一回传入多少个文本,sed会依次拍卖。sed的编辑撰写命令能够直接当命令行参数字传送入,也能够写成三个本子文件然后用-f参数钦定,编辑命令的格式为:

      /pattern/action
    
  • 其间pattern是正则表达式,action是编写操作。sed程序生机勃勃行黄金年代行读出待管理公事,借使某风流倜傥行与pattern匹配,则进行相应的action,假诺一条命令未有pattern而唯有action,那么些action将效能于待管理文件的每生机勃勃行。

  • 常用sed命令

      /pattern/p  打印匹配pattern的行
      /pattern/d  删除匹配pattern的行
      /pattern/s//pattern1/pattern2/  查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2   
      /pattern/s//pattern1/pattern2/g  查找符合pattern的行,将该行所有匹配pattern1的字符串替换为pattern2
    
    • 使用p命令供给注意,sed是把待处理文件的内容及其管理结果一齐输出到正式输出的,由此p命令表示除了把公文内容打字与印刷之外还附加打字与印刷壹回相称pattern的行。譬喻三个文件testfile的剧情是

        123
        abc
        456
      
    • 打字与印刷在那之中积攒abc的行

        $ sed '/abc/p' testfile
        123
        abc
        abc
        456
      
    • 要想只输出管理结果,应充裕-n选项,这种用法相当于grep命令

        $ sed -n '/abc/p' testfile
        abc
      
    • 动用d命令就无需-n参数了,举例删除含有abc的行

        $ sed 'abc/d' testfile
        123
        456
      
    • 在乎,sed命令不会更正原来的作品件,删除命令只表示某个行不打印输出,并不是从原作件中剔除。

    • 接受查找替换命令时,能够把相称pattern1的字符串复制到pattern第22中学,举例:

        $ sed 's/bc/-&-/' testfile
        123
        a-bc-
        456
      
    • 再比如:

        $ sed 's/([0-9])([0-9])/-1-~2~/' testfile
        -1-~2~3
        abc
        -4-~5~6
      
    • pattern2中的1代表与pattern1的第一个()括号相相称的内容,2象征与pattern1的第4个()括号相相称的剧情。sed私下认可使用Basic正则表达式标准,假诺钦点了-r选项则使用Extended标准,那么()括号就无须转义了。如:

        $ sed -r 's/([0-9])([0-9])/-1-~2~/' testfile
      
    • 交替甘休后,全部行,含有接二连三数字的第一个数字前后都增加了"-"号;第叁个数字前后都加多了“~”号。

    • 能够贰遍钦命多条分化的交替命令,用“;”隔绝:

        $ sed 's/yes/no/; s/static/dhcp/' testfile
        注:使用分号隔开指令。
      
    • 也足以使用-e参数来内定差异的替换命令,有多少个替换命令需加多多少个-e参数:

        $ sed -e 's/yes/no/' -e 's/static/dhcp/' testfile
        注:使用-e选项
      
    • 假定testfile的内容是

        <html><head><title>Hello World</title></head>
        <body>Welcome to the world of regexp!</body></html>
      
    • 当今要去掉全数的HTML标签,使出口结果为:

        Hello World
        Welcome to the world of regexp!
      
    • 如何是好呢?如若用下边包车型地铁下令

        $ sed 's/<.*>//g' testfile
      
    • 结果是五个空行,把具有字符都过滤掉了。那是因为,正则表明式中的数量节制符会相配尽也许长的字符串,这叫做贪心的(Greedy卡塔 尔(阿拉伯语:قطر‎。比如sed在管理第后生可畏行时,<.*>相配的而不是或那样的竹签,而是

        <html><head><title>Hello World</title></head>
      
    • 如此一整行,因为那风华正茂行初阶是<,中间是多少个随机字符,末尾是>。那么那条命令怎么改才对啊?留给学生们动脑。

标准化语句和循环语句

看起来基本和C相似,框架如下——

if (条件表达式)
    动作1
[else
    动作2]

while(条件表达式)
    动作

do
    动作
while(条件表达式)

for(设置计数器初值; 测试计数器; 计数器变化)
    动作

awk

  • sed以行为单位拍卖文件,awk比sed强之处在于既可以以行为单位仍可以以列为单位拍卖文件。awk缺省的行分隔符是换行,缺省的列分隔符是连接的空格和Tab,不过行分隔和列分隔符都足以自定义,例如/etc/passwd文件的每意气风发行有多少个字段,字段之间以:分隔,就足以重复定义awk的列分隔符为:并以列为单位拍卖那些文件。awk实际上是一门很复杂的脚本语言,还大概有像C语言相像的道岔和循环结构,不过基本用法和sed相通,awk命令行的中坚格局为:

      awk option 'script' file1 file2 ...
      awk option -f scriptfile file1 file2 ...
    
  • 和sed相仿,awk管理的公文既能由专门的学问输入重定向得到,也足以当命令行参数字传送入,编辑命令能够向来当命令行参数字传送入,也得以用-f参数钦定三个剧本文件,编辑命令的格式为:

      /pattern/{actions}
      condition{actions}
    
  • 和sed类似,pattern是正则表达式,actions是风流浪漫雨后玉兰片操作。awk程序生龙活虎行大器晚成行读出待管理文件,要是某生龙活虎行与pattern相称,或然满意condition条件,则推行相应的actions,即使一条awk命令只有actions部分,则actions作用于待管理文件的每大器晚成行。比如文件testfile的内容表示某商铺的仓库储存量:

      ProductionA 30
      ProductionB 76      
      ProductionC 55
    
  • 打印每大器晚成行的第二列:

      $ awk '{print $2;}' testfile
      30
      76
      55
    
  • 电动变量$1、$2各自代表第一列、第二列等,近似于Shell脚本的岗位参数,而$0表示全体当前进。再举个例子说,如若某种成品的仓库储存量低于75则在末行标明须求预定:

      $ awk '$2<75 {printf "%st%sn", $0, "REORDER";} $2>=75 {print $0;}' testfile
      ProductionA 30 REORDER
      ProductionB 76      
      ProductionC 55 REORDER
    
  • 可知awk也可能有和C语言特别相像的printf函数。awk命令的condition部分仍可以是七个特别的condition——BEGIN和END,对于各样待管理文件,BEGIN前面包车型大巴actions在拍卖整个文件从前实施三遍,END前边的actions在方方面面文件处理完之后试行叁遍。

  • awk命令能够像C语言相仿使用变量(但无需定义变量卡塔 尔(英语:State of Qatar),譬如计算三个文书中的空行数

      $ awk '/^ *$/ {x=x+1;} END {print x;}' testfile
    
  • 就像是Shell的境遇变量同样,有些awk变量是预订义的有至极含义的:

    • awk常用的内建变量

        FILENAME    当前输入文件的文件名,该变量是只读的
        NR          当前行的行号,该变量是只读的,R代表record
        NF          当前行所拥有的列数,该变量是只读的,F代表field
        OFS         输出格式的列分隔符,缺省是空格
        FS          输入文件的列分隔符,缺省是连续的空格和Tab
        ORS         输出格式的行分隔符,缺省是换行符
        RS          输入文件的行分隔符,缺省是换行符
      
  • 比方打字与印刷系统中的客户帐号列表

      $ awk 'BEGIN {FS=":"} {print $1;}' /etc/passwd
    
  • awk也得以像C语言雷同接受if/else、while、for调控结构。可机关扩充学习。

数组

数组是积攒大器晚成多种值的变量,可经过索引来访问数组的值,索引供给用中括号括起,数组的主导格式为:

array[index]=value

款式和C相近,但awk数组无需定义数组类型和分寸,能够一向赋值后采纳。日常用在for循环中

for (variable in array)
    do somethng with array[variable]

更加多操作能够查看:http://man.linuxde.net/awk

参考:Linux Shell编制程序——从初学到理解(第2版卡塔 尔(英语:State of Qatar)

C程序中接纳正则

  • POSIX规定了正则表达式的C语言库函数,详见regex(3)。我们曾经学习了无数C语言库函数的用法,读者应当具有自个儿看懂man手册的力量了。本章介绍了正则表明式在grep、sed、awk中的用法,学习要能够闻一知十,请读者依据regex(3)自个儿计算正则表明式在C语言中的用法,写一些签单的先后,譬喻验证客户输入的IP地址或email地址格式是或不是准确。
  • C语言管理正则表明式常用的函数有regcomp()、regexec()、regfree()、regerror(),平常分为八个步骤,如下所示:
    • 1、编写翻译正则表达式regcomp()
    • 2、匹配正则表达式regexec()
    • 3、释校正则表明式regfree()
  • 下边是对五个函数的详尽表达

    • 1、regcomp()这一个函数把钦点的正则表明式pattern编写翻译成生龙活虎种特定的数据格式compiled,那样能够使十一分更管用。函数regexec会利用这几个数量在对象文本串中举办方式相配。实施成功重临0。
      • int regcomp(regex_t *compiled, const char *pattern, int cflags)
      • regex_t:是二个结构休数据类型,用来寄存在编写翻译后的正则说明式,它的成员re_nsub用来储存正则表达式中的子正则表达式的个数,子正则表达式正是用圆括号包起来的一些表达式。
      • pattern:是指向大家写好的正则表达式的指针。
      • cflags犹如下4个值只怕是它们或运算(|)后的值:
        • REG_EXTENDED:以功效更强硬的强大正则表明式的点子举办相称。
        • REG_ICASE:相配字母时忽视大小写
        • REG_NOSUB:不用存储匹配后的结果,只回去是还是不是成功相配。如果设置该标识位,那么在regexec将忽视nmatch和pmatch三个参数。
        • REG_NEWLINE:识别换行符,那样'$'就足以从行尾开头相称,'^'就能够从行的按键初步相称。
    • 2、当我们编写翻译好正则表明式后,就足以用regexec相称大家的对象文本串了,假设在编写翻译正则表明式的时候未有一点名cflags的参数为REG_NEWLINE,则暗许境况下是忽略换行符的,也便是把任何文本串当做三个字符串管理。

      • 举办成功再次来到0。
      • regmatch_t是一个结构体数据类型,在regex.h中定义:

          typedef struct {
              regoff_t rm_so;
              regoff_t rm_eo;
          } regmatch_t;
        
      • 成员rm_so存放相称文本串在指标串中的起始地方,rm_eo寄存结束地方。通常大家以数组的款型定义后生可畏组那样的布局。因为再三我们的正则表明式中还包涵子正则表明式。数组0单元存放主正则表明式地方,后面包车型大巴单元依次存改良则表明式地点。

      • int regexec(regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr[], int eflags)
        • compiled:是意气风发度用regcomp函数编写翻译好的正则表明式。
        • string:是目的文本串。
        • nmatch:是regmatch_t结构体数组的长度。
        • matchptr:regmatch_t类型的布局体数组,贮存相配文本串的职位音讯。
        • eflags有五个值:
          • REG_NOTBOL:让特殊字符^无坚决守住。
          • REG_NOTEOL:让杰出字符$无效劳。
    • 3、当大家采用完编写翻译好的正则表明式后,可能要再一次编写翻译别的正则表达式的时候,大家可以用那一个函数清空compiled指向的regex_t结构体的剧情,请深深记住,若是是再一次编写翻译的话,一定要先清空regex_t结构体。

      • void regfree(regex_t *compiled)
    • 4、当施行regcomp只怕regexec产生错误的时候,就足以调用那么些函数而回到三个带有错误音信的字符串。
      • size_t regerror(int errcode, regex_t *compiled, char *buffer, size_t length)
        • errcode:是由regcomp和regexec函数重临的失实代号。
        • compiled:是后生可畏度用regcomp函数编写翻译好的正则表明式,那几个值可以为NULL。
        • buffer:指向用来贮存错误新闻的字符串的内部存款和储蓄器空间。
        • length:指明buffer的长度,如若那一个错误新闻的尺寸超过那一个值,则regerror函数会活动截断超过的字符串,但她长久以来会回到完整的字符串的长度。所以大家能够用如下的章程先得到错误字符串的长短。
        • 例如:size_t length = regerror(errcode, compiled, NULL, 0);
    • 测量检验用例:

        #include <sys/types.h>
        #include <regex.h>
        #include <stdio.h>
      
        int main(int argc, char *argv[])
        {
            if(argc != 3){ 
                printf("Usage: %s RegexString And Textn", argv[0]);
            }   
      
            const char * p_regex_str = argv[1];
            const char * p_txt = argv[2];
            //编译后的结构体
            regex_t oregex;
            int ret = 0;
            //保存错误信息的数组
            char emsg[1024] = {0};
            size_t emsg_len = 0;
      
            //编译正则表达式, 扩展正则
            if((ret = regcomp(&oregex, p_regex_str, REG_EXTENDED|REG_NOSUB)) == 0){ 
                //执行匹配,不保存匹配的返回值
                if((ret = regexec(&oregex, p_txt, 0, NULL, 0)) == 0){ 
                    printf("%s matches %sn", p_txt, p_regex_str);
                    regfree(&oregex);
                    return 0;
                }   
            }   
      
            //正则编译错误,存emsg中错误描述
            emsg_len = regerror(ret, &oregex, emsg, sizeof(emsg));
            //错误信息较长特殊情况
            emsg_len = emsg_len < sizeof(emsg)? emsg_len : sizeof(emsg) - 1;
      
            emsg[emsg_len] = '';
            printf("Regex error Msg: %sn", emsg);
      
            regfree(&oregex);
      
            //非正常退出                                                                                             
            return 1;
        }
      
    • 相配网站:

        ./a.out "http://www..*.com" "http://www.taobao.com"
      
    • 协作邮箱:

        ./a.out "^[a-zA-Z0-9.]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+" "abc.123@126.com"
        ./a.out "w+([-+.]w+)*@w+([-+.]w+)*.w+([-+.]w+)*" "abc@qq.com"
      
    • 相称固话号码:请同学们团结编写。

    • 除了GNU提供的函数外,还常用PCRE管理正则,全称是Rerl Compatible Regular Expressions。从名字大家得以看出PCRE库是与Perl中正则表明式相包容的二个正则表明式库。PCRE是无偿开源的库,它是由C语言达成的,这里是它的官方主页:
    • PCRE++是二个对PCRE库的C++封装,它提供了特别有益、易用的C++接口。这里是它的官方主页:

本文由9159.com发布于操作系统,转载请注明出处:grep命令的模式十分灵活,算术代换

关键词: