shell编程学习(shell编程入门)

shell编程学习(shell编程入门)svg xmlns http www w3 org 2000 svg style display none svg

大家好,我是讯享网,很高兴认识大家。



 <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p>为了方便以后工作使用和复习&#xff0c;吐血整理记录一下学习shell脚本的笔记&#xff0c;看这篇文章需要对linux系统熟悉&#xff0c;希望对大家有所帮助&#xff01;</p> 

讯享网

shell是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

为什么要学习和使用shell?

Shell属于内置的脚本,程序开发的效率非常高,依赖于功能强大的命令可以迅速地完成开发任务(批处理)语法简单,代码写起来比较轻松,简单易学



cat /etc/shells
在linux中有很多类型的shell,不同的shell具备不同的功能,shell还决定了脚本中函数的语法,Linux中默认的shell是 ,流行的shell有ash、bash、ksh、csh、zsh等,不同的shell都有自己的特点以及用途。

编写规范:

讯享网

文件命名规范:

文件名.sh     .sh是linux下bash shell 的默认后缀

Bash 常用快捷键

快捷键作用ctrl+A把光标移动到命令行开头。如果我们输入的命令过长,想要把光标移动到命令行开头时使用。ctrl+E把光标移动到命令行结尾。ctrl+C强制终止当前的命令。ctrl+L清屏,相当于clear命令。ctrl+U删除或剪切光标之前的命令。我输入了一行很长的命令,不用使用退格键一个一个字符的删除,使用这个快捷键会更加方便ctrl+K删除或剪切光标之后的内容。ctrl+Y粘贴ctrl+U或ctul+K剪切的内容。ctrl+R在历史命令中搜索,按下ctrl+R之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索。ctrl+D退出当前终端。ctrl+Z暂停,并放入后台。这个快捷键牵扯工作管理的内容,我们在系统管理章节详细介绍。ctrl+S暂停屏幕输出。ctrl+Q恢复屏幕输出。

输入输出重定向

linux 的标准输入与输出
设备设备名文件描述符类型键盘/dev/stdin0标准输入显示器/dev/stdout1标准输出显示器/dev/stderr2标准错误输出
输入重定向

输入重定向:是指不使用系统提供的标准输入端口,而进行重新的指定。换言之,输入重定向就是不使用标准输入端口输入文件,而是使用指定的文件作为标准输入设备。(重定向简单理解就是使用 “&lt;”符来修改标准输入设备)

类型符号(语法)功能标准输入命令&lt;文件1命令把文件1的内容作为标准输入设备标识符限定输入命令&lt;&lt;标识符命令把标准输入中读入内容,直到遇到“标识符”分解符为止输入输出重定向(同时使用)命令&lt; 文件1 &gt;文件2命令把文件1的内容作为标准输入,把文件2作为标准输出。

输出重定向

输出重定向:(通俗的讲,重定向输出就是把要输出的文件信息写入到一个文件中去,而不是将要输出的文件信息输出到控制台(显示屏),在linux中,默认的标准输出设备是控制台(或称为显示器),用户输出的信息默认情况下都会显示到控制台

&表示全部文件,文件不管对错,1表示标准输出文件,2表示标准错误输出。

类型符号作用标住输出重定向命令 &gt; 文件以覆盖方式,把命令的正确输出内容输出到指定的文件或设备当中标住输出重定向命令 &gt;&gt; 文件以追加方式,把命令的正确输出内容输出到指定的文件或设备当中标准错误输出重定向错误命令2 &gt; 文件以覆盖方式,把命令的错误输出输出到指定的文件或设备当中标准错误输出重定向错误命令2 &gt;&gt; 文件以追加方式,把命令的错误输出输出到指定的文件或设备当中正确输出和错误输出同时保存命令 &gt; 文件 2&gt;&1以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。正确输出和错误输出同时保存命令 &gt;&gt; 文件 2&gt;&1以追加的方式,把正确输出和错误输出都保存到同一个文件当中。正确输出和错误输出同时保存命令 &&gt; 文件以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。正确输出和错误输出同时保存命令 &&gt;&gt; 文件以追加的方式,把正确输出和错误输出都保存到同一个文件当中。正确输出和错误输出同时保存命令 &gt;&gt; 文件1 2&gt;&gt;文件2把正确的输出追加到文件1中,把错误的输出追加到文件2中。
/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到/dev/null

 
多命令顺序执行
多命令执行符作用格式;命令1 ;命令2多个命令顺序执行,命令之间没有任何逻辑联系&&命令1 && 命令2当命令1正确执行(?≠0),则命令2不会执行ll命令1 || 命令2当命令1执行不正确(?=0),则命令2不会执行

shell脚本的执行

讯享网

两种方式执行shell脚本

第一种:给文件增加执行权限

 

第二种(了解):通过Bash调用执行脚本

讯享网


什么是变量?
在一个脚本周期内,其值可以发生改变的量就是变量。

1. 变量的命名规则:

在定义变量时,有一些规则需要遵守:

  1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  2. 等号左右两侧不能有空格,可以使用下划线“_”,变量的值如果有空格,需要使用单引号或双引号包括。如:“test=“hello world!””。其中双引号括起来的内容“\(”&#xff0c;“(”和反引号都拥有特殊含义&#xff0c;而<mark>单引号括起来的内容都是普通字符。</mark></li><li>不能使用标点符号&#xff0c;不能使用bash里的关键字&#xff08;可用help命令查看保留关键字&#xff09;。</li><li><mark>环境变量建议大写&#xff0c;便于区分</mark></li><li>如果需要增加变量的值&#xff0c;那么可以进行变量值的叠加。不过变量需要用双引号包含&#34;\)变量名“或用\({变量名}包含变量名。</li></ol> <pre></pre> <p><strong>关于单双引号的问题&#xff1a;<br /> 双引号能够识别变量&#xff0c;双引号能够实现转义&#xff08;类似于“*”&#xff09;<br /> 单引号是不能识别变量&#xff0c;只会原样输出&#xff0c;单引号是不能转义的</strong></p> <br /> <h5>shell中特殊符号</h5> <div><thead><tr><th>符号</th><th>作用</th></tr></thead><tbody><tr><td>’ ’</td><td>单引号。在单引号中所有的特殊符号&#xff0c;如“\)”和”(反引号)都没有特殊含义。单引号括起来的都是普通字符,会原样输出” “双引号。在双引号中特殊符号都没有特殊含义,但是“\(”&#xff0c;“&#96;”&#xff08;esc键下面&#xff09;和“”是例外&#xff0c;拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。</td></tr><tr><td>· ·</td><td>反引号。反引号括起来的内容是系统命令&#xff0c;在Bash中会先执行它。和()&#xff0c;因为反引号非常容易看错。</td></tr><tr><td>\)单引号和双引号()和反引号作用一样,用来引用系统命令。(推荐使用)()用于一串命令执行时,()中的命令会在子Shell中运行{}用于一串命令执行时,{ }中的命令会在当前Shell中执行。也可以用于变量变形与替换。[ ]用于变量的测试。#在Shell脚本中,#开头的行代表注释。\(</td><td>用于调用变量的值&#xff0c;如需要调用变量name的值时&#xff0c;需要用\)name的方式得到变量的值。转义符,跟在之后的特殊符号将失去特殊含义,变为普通字符。如\(将输出“\)”符号,而不当做是变量引用。
     

    反引号

    讯享网

    2. 变量的分类:

    1. 用户自定义变量: 这种变量是最常见的变量,由用户自由定义变量名和变量的值。
    2. 环境变量: 这种变量中主要保存的是和系统操作环境相关的数据,比如当前登录用户,用户的家目录,命令的提示符等。不是太好理解吧,那么大家还记得在Windows中,同一台电脑可以有多个用户登录,而且每个用户都可以定义自己的桌面样式和分辨率,这些其实就是Windows的操作环境,可以当做是Windows的环境变量来理解。环境变量的变量名可以自由定义,但是一般对系统起作用的环境变量的变量名是系统预先设定好的。
    3. 位置参数变量: 这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
    4. 预定义变量: 是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。
    变量分类名称作用内容用户自定义变量自定义自定义自定义用户自定义环境变量自定义自定义自定义系统自带环境变量(/etc/profile)确定确定自定义位置参数变量确定自定义自定义预定义变量确定自定义自定义

    2.1 用户自定义变量:
    2.1.1 变量定义
     
    2.1.2 变量调用
    讯享网
    2.1.3 变量查看
     
    2.1.4 变量删除
    讯享网

    2.2 环境变量:
    2.2.1 环境变量设置
     
    2.2.2 环境变量查询和删除

    env命令和set命令的区别:
    set命令可以查看所有变量,而env命令只能查看环境变量。

    讯享网
    2.2.3 系统默认环境变量
     
    2.3 位置参数变量:
    位置参数变量作用 \(n</td><td>n为数字&#xff0c;\)0表示当前 Shell 脚本程序的名称, \(1-{10}</td></tr><tr><td>\)*这个变量代表命令行中所有的参数, \(把所有的参数看成一个整体</td></tr><tr><td>\)@这个变量也代表命令行中所有的参数,不过 \(&#64;把每个参数区分对待</td></tr><tr><td>\)#这个变量代表命令行中所有参数的个数

    \(1 是你给你写的shell脚本传的第一个参数&#xff0c;\)2 是你给你写的shell脚本传的第二个参数…

    讯享网

    保存退出后,你在Test.sh所在的目录下输入

    结果输出:

     

    \(*会把接收的所有参数当成一个整体对待&#xff0c;而\)@则会区分对待接收到的所有参数。举个例子:

    讯享网

    2.4 预定义变量:
    预定义变量作用 \(?</td><td>最后一次执行的命令的返回状态。如果这个变量的值为0&#xff0c;证明上一个命令正确执行;如果这个变量的值为非О(具体是哪个数&#xff0c;由命令自己来决定&#xff09;&#xff0c;则证明上一个命令执行不正确了。</td></tr><tr><td>\) \(</td><td>当前进程的进程号&#xff08;PID)</td></tr><tr><td>\)!后台运行的最后一个进程的进程号(PID)

    先来看看”\(?”这个变量&#xff0c;举个例子说明</strong></p> <pre></pre> <p><strong>再来说明下”\)\(”和”\)!”这两个预定义变量

     
    3. 只读变量:
    讯享网
    4. 接受键盘输入:
     

    写个例子来解释下read命令:

    讯享网


    在shell中,运算符和其他编程脚本语言一样,常见的有算数运算符、关系运算符、逻辑运算符、字符串运算符、文件测试运算符

    1. 算数运算符

    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
    expr 是一款表达式计算工具,使用它能完成表达式的求值操作
    例如,两个数相加(注意使用的是反引号 ` 而不是单引号 ‘):

     

    下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20

    运算符说明举例
    • |加法 | 结果为 30。
    • |减法 | 结果为 -10。
      *| 乘法 | 结果为 200。
      / |除法 | 结果为 2。
      % |取余| 结果为 0。
      = |赋值| a=\(b 将把变量 b 的值赋给 a。<br /> &#61;&#61;| 相等。用于比较两个数字&#xff0c;相同则返回 true&#xff08;真&#xff09;。| [ \)a == \(b ] 返回 false&#xff08;假&#xff09;。<br /> !&#61; |不相等。用于比较两个数字&#xff0c;不相同则返回 true。 |[ \)a != \(b ] 返回 true。</li></ul> <p>注意&#xff1a;条件表达式要放在方括号之间&#xff0c;并且要有空格&#xff0c;必须写成 [ \)a == \(b ]。</p> <pre></pre> <h4>2. 关系运算符</h4> <p><mark>关系运算符只支持数字&#xff0c;不支持字符串&#xff0c;除非字符串的值是数字。</mark><br /> <strong>下表列出了常用的关系运算符&#xff0c;假定变量 a 为 10&#xff0c;变量 b 为 20&#xff1a;</strong></p> <div><thead><tr><th>运算符</th><th>单词</th><th>说明</th><th>举例</th></tr></thead><tbody><tr><td>-eq</td><td>equal</td><td>检测两个数是否相等&#xff0c;相等返回 true。</td><td>[ \)a -eq \(b ] 返回 false。</td></tr><tr><td>-ne</td><td>not equal</td><td>检测两个数是否相等&#xff0c;不相等返回 true。</td><td>[ \)a -ne \(b ] 返回 true。</td></tr><tr><td>-gt</td><td>great than</td><td>检测左边的数是否大于右边的&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ \)a -gt \(b ] 返回 false。</td></tr><tr><td>-lt</td><td>less than</td><td>检测左边的数是否小于右边的&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ \)文件测试运算符用于检测 Unix/Linux 文件的各种属性。a -lt \(b ] 返回 true。</td></tr><tr><td>-ge</td><td>great than or equal</td><td>检测左边的数是否大于等于右边的&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ \)a -ge \(b ] 返回 false。</td></tr><tr><td>-le</td><td>less than or equal</td><td>检测左边的数是否小于等于右边的&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ \)a -le \(b ] 返回 true。</td></tr></tbody></div> <pre></pre> <p><strong>案例&#xff1a;判断当前输入的用户是否存在。如果存在则提示“用户存在”否则提示“用户不存在”。</strong></p> <p><strong>如果要在shell脚本使用linux命令&#xff0c;可以使用包裹命令</strong><br /> 例如&#xff1a;<strong>disk_size&#61;\)(df -h | awk ‘NR==2 {print \(5}’)</strong></p> <pre></pre> <br /> <h4>3. 逻辑运算符</h4> <p><strong>下表列出了常用的布尔运算符&#xff0c;假定变量 a 为 10&#xff0c;变量 b 为 20&#xff1a;</strong></p> <div><thead><tr><th>运算符</th><th>说明</th><th>举例</th></tr></thead><tbody><tr><td>!</td><td>非运算&#xff0c;表达式为 true 则返回 false&#xff0c;否则返回 true。</td><td>[ ! false ] 返回 true。</td></tr><tr><td>-o</td><td>或&#xff08;或者&#xff09;运算&#xff0c;有一个表达式为 true 则返回 true。</td><td>[ \)a -lt 20 -o \(b -gt 100 ] 返回 true。</td></tr><tr><td>-a</td><td>与&#xff08;并且&#xff09;运算&#xff0c;两个表达式都为 true 才返回 true。</td><td>[ \)a -lt 20 -a \(b -gt 100 ] 返回 false。</td></tr></tbody></div> <p><strong>或运算&#xff1a;一个为真即为真&#xff0c;全部为假才是假<br /> 与运算&#xff1a;一个为假即为假&#xff0c;全部为真才是真</strong></p> <br /> <h4>4. 字符串运算符</h4> <p><strong>下表列出了常用的字符串运算符&#xff0c;假定变量 a 为 “abc”&#xff0c;变量 b 为 “efg”&#xff1a;</strong></p> <div><thead><tr><th>运算符</th><th>说明</th><th>举例</th></tr></thead><tbody><tr><td>&#61;</td><td>检测两个字符串是否相等&#xff0c;相等返回 true。</td><td>[ \)a = \(b ] 返回 false。</td></tr><tr><td>!&#61;</td><td>检测两个字符串是否相等&#xff0c;不相等返回 true。</td><td>[ \)a != \(b ] 返回 true。</td></tr><tr><td>-z</td><td>检测字符串长度是否为0&#xff0c;为0返回 true。</td><td>[ -z \)a ] 返回 false。-n检测字符串长度是否为0,不为0返回 true。[ -n \(a ] 返回 true。</td></tr><tr><td>str</td><td>检测字符串是否为空&#xff0c;不为空返回 true。</td><td>[ \)a ] 返回 true。

      5. 文件测试运算符(重点)

      操作符说明举例-b file检测文件是否是块设备文件,如果是,则返回 true。[ -b \(file ] 返回 false。</td></tr><tr><td>-c file</td><td>检测文件是否是字符设备文件&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ -c \)file ] 返回 false。-d file检测文件是否是目录,如果是,则返回 true。[ -d \(file ] 返回 false。</td></tr><tr><td>-f file</td><td>检测文件是否是普通文件&#xff08;既不是目录&#xff0c;也不是设备文件&#xff09;&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ -f \)file ] 返回 true。-g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g \(file ] 返回 false。</td></tr><tr><td>-k file</td><td>检测文件是否设置了粘着位(Sticky Bit)&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ -k \)file ] 返回 false。-p file检测文件是否是有名管道,如果是,则返回 true。[ -p \(file ] 返回 false。</td></tr><tr><td>-u file</td><td>检测文件是否设置了 SUID 位&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ -u \)file ] 返回 false。-r file检测文件是否可读,如果是,则返回 true。[ -r \(file ] 返回 true。</td></tr><tr><td>-w file</td><td>检测文件是否可写&#xff0c;如果是&#xff0c;则返回 true。</td><td>[ -w \)file ] 返回 true。-x file检测文件是否可执行,如果是,则返回 true。[ -x \(file ] 返回 true。</td></tr><tr><td>-s file</td><td>检测文件是否为空&#xff08;文件大小是否大于0&#xff09;&#xff0c;不为空返回 true。</td><td>[ -s \)file ] 返回 true。-e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

      注意:权限几个判断,如果只有一个部分符合,则认为是有权限的。


      讯享网



      1. if条件判断

      1.1 单分支if条件

      语法:

      讯享网

      案例:统计根分区使用率

       

      案例:创建目录

      讯享网

      1.2 双分支if条件语句

      语法:

       

      案例1:备份mysql数据库

      讯享网

      案例2:判断apache是否启动,如果没有启动则自动启动

       

      nmap端口扫描命令,格式如下:

      讯享网

      1.3 多分支if条件语句

      语法:

       

      案例:判断用户输入的是什么文件

      讯享网

      2. 多分支case条件语句

      case语句和if…elif…else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。

      case语句语法如下:

       

      这个语句需要注意以下内容:

      • case语句,会取出变量中的值,然后与语句体中的值逐一比较。如果数值符合,则执行对应的程序,如果数值不符,则依次比较下一个值。如果所有的值都不符合,则执行 “*)” (*代表所有其他值)中的程序。
      • case语句以“case”开头,以“esac”结尾。

      每一个分支程序之后要通过“;;”双分号结尾,代表该程序段结束(千万不要忘记,每次写case语句,都不要忘记双分号)。

      案例:

      讯享网

      3. for循环

      for循环是固定循环,也就是在循环时已经知道需要进行几次的循环,有时也把for循环称为计数循环。for的语法有如下两种:

      语法一:

       

      语法二:

      讯享网

      语法一举例:打印时间

       

      语法一举例:批量解压缩脚本

      讯享网

      语法二举例:从1加到100

       

      语法二举例:批量添加指定数量的用户

      讯享网

      语法二举例:批量删除用户

       

      4. while循环

      对while循环来讲,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。

      语法:

      讯享网

      案例:1加到100

       

      案例:输入的数值进行比较判断

      讯享网

      5. until循环

      和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。

      语法:

       

      案例一:1加到100

      讯享网

      6. 函数

      语法:

       

      案例:接收用户输入的数字,然后从1加到这个数字

      讯享网

      7. 特殊流程控制语句

      7.1 exit语句

      系统是有exit命令的,用于退出当前用户的登录状态。可是在Shell脚本中,exit语句是用来退出当前脚本的。也就是说,在Shell脚本中,只要碰到了exit语句,后续的程序就不再执行,而直接退出脚本

      exit的语法如下:

       

      如果exit命令之后定义了返回值,那么这个脚本执行之后的返回值就是我们自己定义的返回值。可以通过查询$?这个变量,来查看返回值。如果exit之后没有定义返回值,脚本执行之后的返回值是执行exit 语句之前,最后执行的一条命令的返回值。写一个exit 的例子:

      讯享网
      7.2 break语句

      当程序执行到break语句时,会结束整个当前循环。而continue 语句也是结束循环的语句,不过continue 语句单次当前循环,而下次循环会继续。

      案例:

       

      执行下这个脚本,因为一旦变量i的值等于4,整个循环都会跳出,所以应该只能循环三次:

      讯享网
      7.3 continue语句

      continue也是结束流程控制的语句。如果在循环中,continue语句只会结束单次当前循环。

      案例:

       

      执行下这个脚本:

      讯享网


      正则表达式

      元字符描述示例转义符,将特殊字符进行转义,忽略其特殊意义a.b匹配a.b,但不能匹配ajb,.被转义为特殊意义^匹配行首,awk中,^则是匹配字符串的开始^tux匹配以tux开头的行 \(</td><td>匹配行尾&#xff0c;awk中&#xff0c;\)则是匹配字符串的结尾tux \(匹配以tux结尾的行</td></tr><tr><td>.</td><td>匹配除换行符 之外的任意单个字符</td><td>ab.匹配abc或abd&#xff0c;不可匹配abcd或abde&#xff0c;只能匹配单字符</td></tr><tr><td>[ ]</td><td>匹配包含在[字符]之中的任意一个字符</td><td>coo[kl]可以匹配cook或cool</td></tr><tr><td>[^]</td><td>匹配[^字符]之外的任意一个字符</td><td>123[^45]不可以匹配1234或1235&#xff0c;1236、1237都可以</td></tr><tr><td>[-]</td><td>匹配[]中指定范围内的任意一个字符&#xff0c;要写成递增</td><td>[0-9]可以匹配1、2或3等其中任意一个数字</td></tr><tr><td>?</td><td>匹配之前的项1次或者0次</td><td>colou?r可以匹配color或者colour&#xff0c;不能匹配colouur</td></tr></tbody></div> <ul><li>| 匹配之前的项1次或者多次 | sa-6&#43;匹配sa-6、sa-666&#xff0c;不能匹配sa-</li></ul> <ul><li>| 匹配之前的项0次或者多次| co*l匹配cl、col、cool、coool等<br /> () | 匹配表达式&#xff0c;创建一个用于匹配的子串 | ma(tri)?匹配max或maxtrix<br /> {n} | 匹配之前的项n次&#xff0c;n是可以为0的正整数 |[0-9]{3}匹配任意一个三位数&#xff0c;可以扩展为[0-9][0-9][0-9]<br /> {n,}| 之前的项至少需要匹配n次 | [0-9]{2,}匹配任意一个两位数或更多位数不支持{n,}{n,}{n,}<br /> {n,m}| 指定之前的项至少匹配n次&#xff0c;最多匹配m次&#xff0c;n&lt;&#61;m | [0-9]{2,5}匹配从两位数到五位数之间的任意一个数字<br /> || 交替匹配|两边的任意一项 | ab(c|d)匹配abc或abd</li></ul> <h4>1 字符截取、替换命令</h4> <h5>1.1 cut 列提取命令</h5> <pre></pre> <p>cut命令的默认分隔符是制表符&#xff0c;也就是“tab”键&#xff0c;不过对空格符可是支持的不怎么好啊。我们先建立一个测试文件&#xff0c;然后看看cut命令的作用吧:</p> <pre></pre> <pre></pre> <p>那如果想要提取多列呢?只要列号直接用“&#xff0c;”分开&#xff0c;命令如下:</p> <pre></pre> <p>cut可以按照字符进行提取&#xff0c;需要注意“8-”代表的是提取所有行的第十个字符开始到行尾&#xff0c;而“10-20”代表提取所有行的第十个字符到第二十个字符&#xff0c;而“-8”代表提取所有行从行首到第八个字符:</p> <pre></pre> <pre></pre> <p>如果我想用cut命令截取df命令的第一列和第三列&#xff0c;就会出现这样的情况:</p> <pre></pre> <br /> <h5>1.2 awk 编程</h5> <h6>1.2.1 awk 概述</h6> <p>AWK 是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。</p> <h6>1.2.2 printf 格式化输出</h6> <pre></pre> <p>为了演示printf命令&#xff0c;我们需要修改下刚刚cut命令使用的student.txt文件&#xff0c;文件内容如下:</p> <pre></pre> <p>如果不想把成绩当成字符串输出&#xff0c;而是按照整型和浮点型输出&#xff0c;则要这样:</p> <pre></pre> <h6>1.2.3 awk 基本使用</h6> <pre></pre> <p>我们这里先来学习awk基本用法&#xff0c;也就是只看看格式化输出动作是干什么的。</p> <pre></pre> <p>比如刚刚截取df命令的结果时&#xff0c;cut命令已经力不从心了&#xff0c;我们来看看awk命令:</p> <pre></pre> <h6>1.2.4 awk 的条件</h6> <div><thead><tr><th>条件的类型</th><th>条件</th><th>说明</th></tr></thead><tbody><tr><td>awk保留字</td><td>BEGIN</td><td>在awk程序一开始时&#xff0c;尚未读取任何数据之前执行。BEGIN后的动作只在程序开始时执行一次</td></tr><tr><td>awk保留字</td><td>END</td><td>在awk程序处理完所有数据&#xff0c;即将结束时执行。END后的动作只在程序结束时执行一次</td></tr><tr><td>关系运算符</td><td>&gt;</td><td>大于</td></tr><tr><td>关系运算符</td><td>&lt;</td><td>小于</td></tr><tr><td>关系运算符</td><td>&gt;&#61;</td><td>大于等于</td></tr><tr><td>关系运算符</td><td>&lt;&#61;</td><td>小于等于</td></tr><tr><td>关系运算符</td><td>&#61;&#61;</td><td>等于。用于判断两个值是否相等&#xff0c;如果是给变量赋值&#xff0c;请使用“”号</td></tr><tr><td>关系运算符</td><td>!&#61;</td><td>不等于</td></tr><tr><td>关系运算符</td><td>A~B</td><td>判断字符串A中是否包含能匹配B表达式的子字符串</td></tr><tr><td>关系运算符</td><td>A!~B</td><td>判断字符串A中是否不包含能匹配B表达式的子字符串</td></tr><tr><td>正则表达式</td><td>/正则/</td><td>如果在&#34;//&#34;中可以写入字符&#xff0c;也可以支持正则表达式</td></tr></tbody></div> <h6>BEGIN</h6> <p>BEGIN是awk的保留字&#xff0c;是一种特殊的条件类型。BEGIN的执行时机是“在 awk程序一开始时&#xff0c;尚未读取任何数据之前执行”。一旦BEGIN后的动作执行一次&#xff0c;当awk开始从文件中读入数据&#xff0c;BEGIN的条件就不再成立&#xff0c;所以BEGIN定义的动作只能被执行一次。<br /> 例如:</p> <pre></pre> <h6>END</h6> <p>END也是awk保留字&#xff0c;不过刚好和BEGIN相反。END是在awk程序处理完所有数据&#xff0c;即将结束时执行。END后的动作只在程序结束时执行一次。例如:</p> <pre></pre> <h6>关系运算符</h6> <p>举几个例子看看关系运算符。假设我想看看平均成绩大于等于87分的学员是谁&#xff0c;就可以这样输入命令:<br /> <strong>例子1:</strong></p> <pre></pre> <p>加入了条件之后&#xff0c;只有条件成立动作才会执行&#xff0c;如果条件不满足&#xff0c;则动作则不运行。通过这个实验&#xff0c;大家可以发现&#xff0c;虽然awk是列提取命令&#xff0c;但是也要按行来读入的。这个<strong>命令的执行过程</strong>是这样的:</p> <p><strong>1&#xff09;如果有BEGIN条件&#xff0c;则先执行BEGIN定义的动作。<br /> 2&#xff09;如果没有BEGIN条件&#xff0c;则读入第一行&#xff0c;把第一行的数据依次赋予\)0、 \(1、\)2等变量。其中 \(0代表此行的整体数据&#xff0c;\)1代表第一字段, \(2代表第二字段。<br /> 3&#xff09;依据条件类型判断动作是否执行。如果条件符合&#xff0c;则执行动作&#xff0c;否则读入下一行数据。如果没有条件&#xff0c;则每行都执行动作。<br /> 4&#xff09;读入下一行数据&#xff0c;重复执行以上步骤。</strong></p> <p>再举个例子&#xff0c;如果我想看看Sc用户的平均成绩呢:</p> <p><strong>例子2:</strong></p> <pre></pre> <p>这里要注意在awk中&#xff0c;使用“//”包含的字符串&#xff0c;awk命令才会查找。也就是说字符串必须用“//”包含&#xff0c;awk命令才能正确识别。</p> <h6>正则表达式</h6> <p>如果要想让awk 识别字符串&#xff0c;必须使用“//”包含&#xff0c;例如:<br /> <strong>例子1:</strong></p> <pre></pre> <p>当使用df命令查看分区使用情况是&#xff0c;如果我只想查看真正的系统分区的使用状况&#xff0c;而不想查看光盘和临时分区的使用状况&#xff0c;则可以:</p> <p><strong>例子2:</strong></p> <pre></pre> <h6>1.2.5 awk 内置变量</h6> <div><thead><tr><th>awk内置变量</th><th>作用</th></tr></thead><tbody><tr><td>\)0代表目前awk所读入的整行数据。我们已知awk是一行一行读入数据的, \(0就代表当前读入行的整行数据。</td></tr><tr><td>\)n代表目前读入行的第n个字段。比如, \(1表示第1个字段(列)&#xff0c;\)2表示第2个字段(列),如此类推NF当前行拥有的字段(列)总数。NR当前awk所处理的行,是总数据的第几行。FS用户定义分隔符。awk的默认分隔符是任何空格,如果想要使用其他分隔符(如“:”),就需要FS变量定义。ARGC命令行参数个数。ARGV命令行参数数组。FNR当前文件中的当前记录数(对输入文件起始为1)。OFMT数值的输出格式(默认为%.6g)。OFS输出字段的分隔符(默认为空格)。ORS输出记录分隔符(默认为换行符)。RS输入记录分隔符(默认为换行符)。
      awk常用统计实例
       
      讯享网

      这里“:”分隔符生效了,可是第一行却没有起作用,原来我们忘记了“BEGIN”条件,那么再来试试;

       
      讯享网

      如果我只想看看sshd这个伪用户的相关信息,则可以这样使用:

       
      1.2.6 awk 流程控制

      我们再来利用下student.txt文件做个练习,后面的使用比较复杂,我们再看看这个文件的内容:

      讯享网

      我们先来看看该如何在awk中定义变量与调用变量的值。假设我想统计PHP成绩的总分,那么就应该这样:

       
          

      我们解释下这个命令。“NR==2 {iphp1=\(3}” (条件是NR&#61;&#61;2&#xff0c;动作是php1&#61;\)3) 这句话是指如果输入数据是第二行(第一行是标题行),就把第二行的第三字段的值赋予变量“php1”。
      “NR==3 {php2=\(3}&#34; 这句话是指如果输入数据是第三行,就把第三行的第三字段的值赋予变量“php2”。“NR&#61;&#61;4 {php3&#61;\)3;totle=phpl+php2+php3;print “totle php is ” totle}”(“NR==4”是条件,后面(中的都是动作)这句话是指如果输入数据是第四行﹐就把第四行的第三字段的值赋予变量“php3”;然后定义变量totle的值是“php1+php2+php3”;然后输出“totle php is”关键字,后面加变量totle的值。

      在awk编程中,因为命令语句非常长,在输入格式时需要注意以下内容:

      多个条件 {动作} 可以用空格分割,也可以用回车分割。

      在一个动作中,如果需要执行多个命令,需要用 “;” 分割,或用回车分割。

      在awk中,变量的赋值与调用都不需要加入“$”符。

      条件中判断两个值是否相同,请使用 “==”,以便和变量赋值进行区分。

      在看看该如何实现流程控制,假设如果Linux成绩大于90,就是一个好男人(学PHP的表示压力很大!) :

      讯享网

      其实在 awk中 if判断语句,完全可以直接利用awk自带的条件来取代,刚刚的脚本可以改写成这样:

       
      1.2.7 awk 函数

      awk编程也允许在编程时使用函数,我们讲讲awk的自定义函数。awk函数的定义方法如下:

      讯享网

      我们定义一个简单的函数,使用函数来打印student.txt的学员姓名和平均成绩,应该这样来写函数:

       
      1.2.8 awk 中调用脚本
      讯享网

      然后可以使用“一f”选项来调用这个脚本:

       
      1.3 sed 文本选取、替换、删除、新增的命令

      sed主要是用来将数据进行选取、替换、删除、新增的命令。

      语法:

      讯享网

      对sed命令大家要注意,sed所做的修改并不会直接改变文件的内容(如果是用管道符接收的命令的输出,这种情况连文件都没有),而是把修改结果只显示到屏幕上,除非使用“-i”选项才会直接修改文件。

      1.3.1 提取行数据

      我们举几个例子来看看sed命令到底是干嘛的。假设我想查看下student.txt的第二行,那么就可以利用“p”动作了:

       

      指定输出某行,使用-n选项

      讯享网
      1.3.2 删除行数据
       
      1.3.3 追加插入行数据
      讯享网

      “a”会在指定行后面追加入数据,如果想要在指定行前面插入数据,则需要使用“i”动作:

       

      如果是想追加或插入多行数据,除最后一行外,每行的末尾都要加入“”代表数据未完结。再来看看“-n”选项的作用:

      讯享网
      1.3.4 替换行数据
       
      讯享网
      1.3.5 字符串替换

      “c”动作是进行整行替换的,如果仅仅想替换行中的部分数据,就要使用“s”动作了。g 使得 sed 对文件中所有符合的字符串都被替换, 修改后内容会到标准输出,不会修改原文件。

       

      替换的格式和vim非常类似,假设我觉得我自己的PHP成绩太低了,想作弊给他改高点,就可以这样来做:

      讯享网

      这样看起来就比较爽了吧。如果我想把AAA老师的成绩注释掉,让他不再生效。可以这样做:

       

      在sed中只能指定行范围,所以很遗憾我在他们两个的中间,不能只把他们两个注释掉,那么我们可以这样:

      讯享网

      “-e”选项可以同时执行多个sed动作,当然如果只是执行一个动作也可以使用“-e”选项,但是这时没有什么意义。还要注意,多个动作之间要用“;”号或回车分割,例如上一个命令也可以这样写:

       

      2 字符处理命令

      2.1 sort 排序命令
      讯享网

      案例:

      sort命令默认是用每行开头第一个字符来进行排序的,比如:

       

      如果想要反向排序,请使用“-r”选项:

      讯享网

      如果想要指定排序的字段,需要使用“-t”选项指定分隔符,并使用“-k”选项指定字段号。加入我想要按照UID字段排序/etc/passwd文件:

       

      因为sort默认是按照字符排序,前面用户的UID的第一个字符都是1,所以这么排序。要想按照数字排序,请使用“-n”选项:

      讯享网

      当然“-k”选项可以直接使用“-k 3”,代表从第三字段到行尾都排序(第一个字符先排序,如果一致,第二个字符再排序,知道行尾)。

      2.2 uniq 取消重复行
       
      2.3 wc 统计命令
      讯享网

小讯
上一篇 2025-04-14 15:16
下一篇 2025-05-27 15:59

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/146299.html