【Linux编程Shell自动化脚本】03 shell四剑客(find、sed、grep、awk)

文章目录

    • 一、find
      • 1. 常用expression
      • 2. 时间参数
      • 3. 其他选项参数
        • 3.1 查找深度
        • 3.2 执行命令
    • 二、sed
      • 1. 常用命令选项
      • 2. 常用动作脚本命令
        • 2.1 s 替换
        • 2.2 已匹配字符串标记&
        • 2.3 在当前行前后插入文本 a\ 和 i\
        • 2.4 p 打印指定行
        • 2.5 匹配行的方式
          • 2.5.1 以数字形式指定行区间
          • 2.5.2 用文本模式指定行区间
    • 三、grep
      • 1. 常用选项
      • 2. 示例
    • 四、awk
        • 1. 常用选项参数
        • 2. 脚本命令
        • 3. 脚本命令中常见的内建变量
        • 4. 实例

一、find

语法格式

find [path] [expression]

参数说明 :

path 是要查找的目录路径,可以是一个目录或文件名,也可以是多个路径,多个路径之间用空格分隔,如果未指定路径,则默认为当前目录。

expression 是可选参数,用于指定查找的条件,可以是文件名、文件类型、文件大小等等。

1. 常用expression

以下列出最常用expression的部分:

  • -name pattern:按文件名查找,支持使用通配符 * 和 ?。
  • -type type:按文件类型查找,可以是 f(普通文件)、d(目录)、l(符号链接)等。
  • -size [+-]size[cwbkMG]:按文件大小查找,支持使用 + 或 - 表示大于或小于指定大小,单位可以是 c(字节)、w(字数)、b(块数)、k(KB)、M(MB)或 G(GB)。
  • -mtime days:按修改时间查找,支持使用 + 或 - 表示在指定天数前或后,days 是一个整数表示天数。
  • -user username:按文件所有者查找。
  • -group groupname:按文件所属组查找。

2. 时间参数

find 命令中用于时间的参数如下:

  • -amin n:查找在 n 分钟内被访问过的文件。
  • -atime n:查找在 n*24 小时内被访问过的文件。
  • -cmin n:查找在 n 分钟内状态发生变化的文件(例如权限)。
  • -ctime n:查找在 n*24 小时内状态发生变化的文件(例如权限)。
  • -mmin n:查找在 n 分钟内被修改过的文件。
  • -mtime n:查找在 n*24 小时内被修改过的文件。

在这些参数中,n 可以是一个正数、负数或零。正数表示在指定的时间前修改或访问过的文件,负数表示在指定的时间内修改或访问过的文件,零表示在当前时间点上修改或访问过的文件。

例如:-mtime 0 表示查找今天修改过的文件,-mtime -7 表示查找过去一周以内修改过的文件。

关于时间 n 参数的说明:

  • +n:查找比 n 天前更早的文件或目录。
  • -n:查找在 n 天内更改过属性的文件或目录。
  • n:查找在 第 n 天前(指定那一天)更改过属性的文件或目录。

3. 其他选项参数

3.1 查找深度

  • -maxdepth levels
    Descend at most levels (a non-negative integer) levels of directories below the starting-points. Using -maxdepth 0 means only apply the tests and actions to the starting-points themselves.
  • -mindepth levels
    Do not apply any tests or actions at levels less than levels (a non-negative integer). Using -mindepth 1 means process all files except the starting-points.

3.2 执行命令

  • -exec command ;
    Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ‘;’ is encountered. The string ‘{}’ is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a ‘\’) or quoted to protect them from expansion by the shell.

示例

# 查找当前目录下当天修改过的txt文件并删除
find . -maxdepth 1 -type f -name "\*.txt" -mtime -1 -exec rm -rf '{}' \;
# 查找当前目录下近5天内修改过的txt文件并拷贝到/tmp目录下
find . -maxdepth 1 -type f -name "\*.txt" -mtime -5 -exec cp '{}' /tmp/ \;

Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though single quotes could have been used in that case also.

注意:cp、mv不能直接使用xargs。
示例

$ find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir

此处的xargs将会构建如下命令:

$ mv 1.csv 2.csv 3.csv ... -t some_dir

如果直接使用cp或mv,会导致目标目录无法匹配,因此,需使用-t指定目标目录

二、sed

Vim 采用的是交互式文本编辑模式,可以用键盘命令来交互性地插入、删除或替换数据中的文本。但 sed 命令不同,它采用的是流编辑模式,最明显的特点是,在 sed 处理数据之前,需要预先提供一组规则,sed 会按照此规则来编辑数据。

vim 中一些常用操作:

  • gg(命令模式下跳转文件开头)
  • G(命令模式下跳转文件结尾)
  • :%s/vivian/sky/替换每一行的第一个 vivian 为 sky(底线命令模式)
  • :%s/vivian/sky/g替换每一行中所有 vivian 为 sky(底线命令模式)

sed 会根据脚本命令来处理文本文件中的数据,这些命令要么从命令行中输入,要么存储在一个文本文件中,此命令执行数据的顺序如下:

  1. 每次仅读取一行内容;
  2. 根据提供的规则命令匹配并修改数据。注意,sed 默认不会直接修改源文件数据,而是会将数据复制到缓冲区中,修改也仅限于缓冲区中的数据;
  3. 将执行结果输出。

当一行数据匹配完成后,它会继续读取下一行数据,并重复这个过程,直到将文件中所有数据处理完毕。

1. 常用命令选项

默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容。

命令选项:

  • -i:此选项会直接修改源文件,要慎用。
  • -n:默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容,而该选项会屏蔽启动输出,需使用 print 命令来完成输出。
  • -e:该选项会将其后跟的脚本命令添加到已有的命令列表中,即可以通过-e参数指定多个命令内容。

2. 常用动作脚本命令

2.1 s 替换

此命令的基本格式为:

[address]s/pattern/replacement/flags

其中,address 表示指定要操作的具体行,pattern 指的是需要替换的内容,replacement 指的是要替换的新内容。

此命令中常用的 flags 标记如表所示

flags 标记 功能
n 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个标记;
g 对数据中所有匹配到的内容进行替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A;
p 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。

示例

sed 's/192/10/g' test.txt  # 把文件里面的192字符替换为10,不修改原文件,替换结果输出到终端
sed -i 's/192/10/g' test.txt  # 把文件里面的192字符替换为10,修改原文件

2.2 已匹配字符串标记&

& 表示已匹配的字符串标记

示例

sed 's/^/& /g' test.txt   # 在每行行首增加一个空格
sed 's/$/& id /g' test.txt   # 在每行末尾增加一个id字符串

2.3 在当前行前后插入文本 a\ 和 i\

a 命令表示在指定行的后面附加一行,i 命令表示在指定行的前面插入一行,它们的基本格式完全相同,如下所示:

[address]a(或 i)\新文本内容

a\ 和 i\ 后面的\可以省略

示例

sed '/^test/a\this is a test line' file	# 在file文件以 test 开头的行后面追加一行文本
sed '/^test/i\this is a test line' file # 在file文件以 test 开头的行前面插入一行文本

2.4 p 打印指定行

p 命令表示搜索符号条件的行,并输出该行的内容,此命令的基本格式为:

[address]p

示例

sed -n '/xxx/p' test.txt

用 -n 选项和 p 命令配合使用,可以禁止输出其他行,只打印包含匹配文本模式的行。

2.5 匹配行的方式

默认情况下,sed 命令会作用于文本数据的所有行。如果只想将命令作用于特定行或某些行,则必须写明 address 部分,表示的方法有以下 2 种:

  1. 以数字形式指定行区间;
  2. 用文本模式指定具体行区间。
2.5.1 以数字形式指定行区间

sed 会将文本流中的第一行编号为 1,然后继续按顺序为接下来的行分配行号。
在脚本命令中,指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行。

示例

sed -n '1p' test.txt  # 打印第一行
sed -n '1,5p' test.txt  # 打印第1-5行

可以使用分号来分隔需要指定的多个行,示例:

sed -n '1p;$p' test.txt  # 打印第一行和最后一行,$符号映射特殊行——最后一行
2.5.2 用文本模式指定行区间

sed 允许指定文本模式来过滤出命令要作用的行,格式如下:

/pattern/command

例如想修改用户 demo 的默认 shell,可以使用 sed 命令,执行命令如下:

sed '/demo/s/bash/csh/' /etc/passwd

输出指定行:

sed -n '/aaa/p' test.txt 

sort命令用于将文本文件内容加以排序。

  • -n 按算术值对字段进行数字排序
  • -r 按倒序排序

三、grep

基本格式:

grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

1. 常用选项

常用选项及含义:

  • -v:列出没有匹配到的行
  • -n:在每一匹配行前列出行号
  • -E, --extended-regexp:将pattern解释为扩展正则表达式,即强制grep表现为egrep(grep -E等价于egrep)

2. 示例

grep -v "^$"   # 排除空行
grep "^10" test.txt  # 匹配以10开头的
grep "11$" test.txt  # 以11结尾的
grep "[0-9]" test.txt  # 匹配数字
grep "[a-z]" test.txt  # 匹配字母

cat -n 打印行号

四、awk

和 sed 命令类似,awk 命令也是逐行扫描文件(从第 1 行到最后一行),寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作;反之,则不对行做任何处理。

此命令的设计者有 3 位,他们的姓分别是 Aho、Weingberger 和 Kernighan,awk 就取自这 3 为大师姓的首字母。

基本格式:

awk [选项参数] '脚本命令' 文件名
标准输出 | awk [选项参数] '脚本命令'   # 如cat test.txt | awk '{print $1}'

1. 常用选项参数

常用选项及含义:

  • -F fs:指定以 fs 作为输入行的分隔符,awk 命令默认分隔符为空格或制表符。

2. 脚本命令

基本格式:

'匹配规则{执行命令}'

这里的匹配规则,和 sed 命令中的 address 部分作用相同,用来指定脚本命令可以作用到文本内容中的具体行,可以使用字符串(比如 /demo/,表示查看含有 demo 字符串的行)或者正则表达式指定。另外需要注意的是,整个脚本命令是用单引号(‘’)括起,而其中的执行命令部分需要用大括号({})括起来。

在 awk 程序执行时,如果没有指定执行命令,则默认会把匹配的行输出;如果不指定匹配规则,则默认匹配文本中所有的行。

3. 脚本命令中常见的内建变量

默认情况下,awk 会将如下变量分配给它在文本行中发现的数据字段:

  • $0 代表整个文本行;
  • $n 代表文本行中的第 n 个数据字段,字段间由FS分隔。

其他内建变量:

  • FS 字段分隔符(默认是任何空格)
  • NF 一条记录的字段的数目,$NF表示匹配文本行的最后一个字段
  • NR 已经读出的记录数,就是行号,从1开始

4. 实例

awk '{print $1}' test.txt  # 打印第一列
awk '{print $NF}' test.txt  # 打印最后一列
awk -F: '{print $1}' /etc/passwd  # 以:作为分隔符打印第一列,取出系统用户名
awk '{print "01: "$NF}' test.txt # 打印最后一列,awk中可以使用""添加输出内容

df -h 查看磁盘占用的空间

你可能感兴趣的:(Linux,Shell,linux,自动化,服务器,bash)