欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Shell 编程入门(四)

程序员文章站 2022-06-08 23:02:19
...

find

find 是 Linux 上最常用的查找文件名的命令。

find 基本语法:

find PATH -name FILENAME
  • PATH:查找路径。
  • -name:是 find 的参数选项,-name 选项后面跟文件名。
  • FILENAME:是查找的文件名。

查找当前目录里的 redis.conf 文件:

find ./ -name "redis.conf"

Shell 编程入门(四)

通配符:

  • *:匹配未知的多个字符。
  • :匹配未知的一个字符。

通配符的小示例:

Shell 编程入门(四)

find 命令除了 -name 之外,还有以下常用的参数:

Shell 编程入门(四)

参数与参数之间可以组合使用:

Shell 编程入门(四)

很多情况下,找到文件后可能会有一些其他的操作,比如删除,改权限,所以,我们在找到文件后一般还会在后面跟上其他的命令:

Shell 编程入门(四)

注:find 完之后,跟上 -exec 参数选项,后跟要执行的命令,{} 会替换成前面找到的文件,必须以 \; 结尾,固定写法。

grep

grep 与 find 不同的是,它可以通过正则来搜索文本的内容

基本语法:

grep [可选项] '需要匹配的字符' 文件名

示例:在当前这一层目录下的所有文件内容中查找 “not” 字符串。

grep "not" *

Shell 编程入门(四)

打印出所在的行:

grep -n "not" *

Shell 编程入门(四)

其他的一些常用参数:

Shell 编程入门(四)

我们一般是把 findgrep 命令通过管道组合起来使用,实现在指定文件中查找指定内容:

# 在当前目录下(就这一层)所有的 .sh 文件中去查找内容包含 "not" 的行,并显示行号
find ./ -maxdepth 1 -name "*.sh" | xargs grep -n "not"

Shell 编程入门(四)

注:加上 xargs 参数表示 grep 会从前面查找出来的每一个文件的内容里面去查找,也就是作为 grep -n "not" * 中的 *。如果不加 xargs 参数,就表示从前面的文件名中去查找,把前面查找出来的所有文件名做为一个文件的内容去查找。

sed

sed 主要用于对文件的 添加,插入,删除,替换,从其他文件中读入数据等,它对文本的处理是以为单位的。

基本语法:

sed [options] 'command' file

options 是 sed 可以接受的参数:

  • -n:只有被处理的行才打印出来,其他的不打印
  • -i:直接修改读取文件内容,不输出到屏幕上
  • -e:多条件编辑

command 是 sed 的命令集:

  • a\:在当前行下面插入文本
  • i\:在当前行上面插入文本
  • c\:把选定的行改为新的文本
  • d:删除选择的行
  • s:替换指定字符
  • p:复制匹配的行
  • r:从外部文件中读取文本

关于 sed 的几个小demo:

注:以下的几个小 demo 均不直接修改文件,如果想修改文件需要加上 -i 参数。

测试文件 myfun.sh 文件的内容如下:

#!/bin/bash
_checkFileExists(){
    if [ -f $1 ]; then
        echo "File:$1 exists"
    else
        echo "File:$1 not exist"
    fi
}
  1. 将 myfun.sh 文件中的 if 替换成 hello

    sed 's/if/hello/g' myfun.sh

    Shell 编程入门(四)

    注:g 表示全局匹配。

  2. 使用 -e 参数进行多条件替换:

    sed -e 's/if/hello/g' -e 's/fi/shell/g' myfun.sh

    Shell 编程入门(四)

  3. 删除含有 if 的行:

    sed '/if/d' myfun.sh

    Shell 编程入门(四)

  4. 删除第 4 行:

    sed '4d' myfun.sh

    Shell 编程入门(四)

  5. 删除 4~5 行:

    sed '4,5d' myfun.sh

    Shell 编程入门(四)

  6. 删除最后一行:

    sed '$d' myfun.sh

    Shell 编程入门(四)

  7. 删除 2~最后一行:

    sed '2,$d' myfun.sh

    Shell 编程入门(四)

  8. 在匹配到 if 行的上一行插入 hello:

    sed '/if/i\hello' myfun.sh

    Shell 编程入门(四)

  9. 在匹配到 if 行的下一行插入 hello shell:

    
    # a\后面的字符串可以有空格
    
    sed '/if/a\hello shell' myfun.sh

    Shell 编程入门(四)

  10. 将匹配到 if 的行替换成 shell script:

    sed '/if/c\shell script' myfun.sh

    Shell 编程入门(四)

  11. 复制包含 if 的行:

    sed '/if/p' myfun.sh

    Shell 编程入门(四)

  12. 将 a.sh 文件中的内容追加到匹配 if 的行下面:

    sed '/if/r a.sh' myfun.sh

    Shell 编程入门(四)

  13. 将匹配到的 if 替换成 shell 并作用于源文件:

    sed -i 's/if/shell/g' myfun.sh

    Shell 编程入门(四)

awk

sed 是用来对文本进行处理的,而 awk 则是用来对文本进行处理的。

它是按行读取文本并视为一条记录,每条记录再分割成若干字段,然后输出各字段的值。

awk 认为文件都是结构化的,也就是说都是由单词和各种空白字符组成的,这里的“空白字符”包括空格、Tab,以及连续的空格和 Tab 等。每个非空白的部分叫做 “” ,从左到右依次是第一个域、第二个域等等,分别用 $1 , $2 …. 来表示, $0 表示全部域。

基本语法:

awk [options] 'script' var=value file(s)

options 常用的命令选项:

  • -F:后跟指定输入分隔符(如果不指定就默认以空白符作为分隔符

示例:

awk -F: '{print $1}' /etc/passwd

解释:以 : 为分隔符,打印出 /etc/passwd 文件中的第一列文本。

Shell 编程入门(四)

上面的例子中脚本的内容只是简单的打印了一下匹配到的行的第一列的文本内容,再看一下 awk 的脚本的详细结构:

awk 'BEGIN{print "start"} pattern{commands} END{print "end"}' file

一脸懵逼,解释一下 'BEGIN{print "start"} pattern{commands} END{print "end"}' 这段脚本的意思:

  1. 在命令执行开始的时候执行 BEGIN{} 里面的操作,即:打印 “start”。
  2. 对于 pattern 匹配到的每一行,执行 {} 里面的操作。
  3. 在命令执行最后的时候执行 END{} 里面的操作,即:打印 “end”。

注: BEGIN{..}END{..}pattern{..} 都是可选的,也就是说可以像上面的第一个针对 awk 的例子那样在脚本中只写一个 {},然后在括号里面写具体的操作。

上面的 pattern 可以是以下任意一个:

  • /正则表达式/:使用通配符的扩展集。
  • 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。
  • 模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
  • BEGIN语句块、pattern语句块、END语句块

上面 {} 里面所执行的操作可以是:

  • 由一个或多个命令,函数,表达式组成,之间由分号隔开。
  • 变量或数组赋值。
  • 输出命令。
  • 内置函数
  • 控制流语句。

再看一个较第一个 awk 例子稍微复杂一点的例子吧:

打印 myfun.sh 文件中匹配到 “fi” 的行,并且在打印前输出 “start”,打印后输出 “end”:

awk 'BEGIN{print "start"} /fi/{print $0} END{print "end"}' myfun.sh

Shell 编程入门(四)

awk 的用法远不止这些,由于 awk 命令的用法过于复杂,所以被列为了一种编程语言

我们编写的 shell 脚本,或者运行在 Linux 服务器上的一些程序有时可能会出现死循环或者假死状态,如果不做处理,就会导致系统资源最终被耗光,不得不重启,这就需要我们通过 kill 命令杀掉这些进程,而杀掉进程我们就需要知道进程的 PID,要想知道进程的 PID 就必须知道运行这个进程的命令是什么,通常这个命令与我们程序的名字,文件的名字有关,我们知道了这个文件的名字之后再通过 ps 命令加 grep 命令找到对应的那一行进程信息,找到 PID ,然后 kill -9 PID 杀掉对应的进程,但是查找的进程有多个,我们岂不是要一个一个删?那可不可以写个脚本来批量删除与之相关的进程呢?

看一个经常用来杀死后台进程的例子:

ps ux|grep test.py|grep -v grep|awk '{print $2}'|xargs kill -9

解释:

  1. ps ux:列出所有的进程。
  2. grep test.py:找到其中包含 test.py 的进程信息。
  3. grep -v grep:去掉 grep 本身这个命令信息。
  4. awk '{print $2}':找到第二列(PID)。
  5. xargs:将前面命令的执行结果作为后面命令的参数。
  6. kill -9:杀掉对应的 PID。
相关标签: grep sed awk