Shell 三剑客是 grepsedawk 三个工具的简称,因功能强大,使用方便且使用频率高,因此被戏称为三剑客。三者均用于处理文本,但各自侧重点不同。

剑客特长
grep查找、匹配文本,仅筛选不修改
sed文本替换、删除、插入,常用于自动化处理任务
awk复杂计算、格式处理

# grep

# 基础语法

grep [选项] "模式" [文件...]

# 常用选项

  • -i :忽略大小写进行匹配。
  • -v :反向查找,只打印不匹配的行。
  • -n :显示匹配行的行号。
  • -r :递归查找子目录中的文件。
  • -l :只打印匹配的文件名。
  • -c :只打印匹配的行数。
  • -E : 启用扩展正则表达式

如果不指定任何选项的话,将直接输出所有包含搜索模式的行,不显示其他信息(如行号、文件名等);

如果指定多个选项,直接合并即可,如 grep -in "hello" file.txt

# 模式

可以是以下三种:

  • 普通字符串
  • 基础正则表达式
  • 扩展正则表达式(选项需要有 -E

# 实用示例

下图是 helloworld.c 文件的内容

image-20250331214717793

  • grep -in "hello" helloworld.c

    作用:不区分大小写、显示行号,查找 helloworld.c 中的 “hello”

    输出: 4: print("Hello World!");

  • grep -ci "hello" helloworld.c

    作用:不区分大小写,统计 “hello" 出现次数

    输出: 1

  • grep -E "\(.+\)" helloworld.c

    作用:启用扩展正则表达式,匹配内容

    输出: print("Hello World!");

  • cat helloworld.c | grep -v "print"

    作用:管道结合,过滤含有 print 的行

    输出:

    #include <stdio.h>
    int main()
    {
            return 0;
    }

# sed

sed 是一种流编辑器,它是文本处理中非常适中的工具,能够完美的配合正则表达式使用。处理时,把当前处理的 ’行‘ 存储在临时缓冲区中,又称为 ‘模式空间’(pattern space) ,接着使用 sed 命令再去处理缓冲区中的内容,处理完成后,把缓冲区的内容输出到屏幕上,接着再去处理下一行,这样不断重复,知道处理到文件的末尾,文件内容并没有改变(也可以指定选项,直接修改文件)

# 基础语法

sed [选项] '命令' [文件]

# 常用选项

sed 默认输出文件的全部内容,并且不会对原文件作修改

  • -n : 只输出匹配到的内容,这个选项一般只用于查看

  • -i : 直接修改原文件内容

  • -r : 支持扩展正则表达式

  • -e : 匹配多个命令

# 常用命令

  • <行号>a<内容> : 新增,在行号后新增一行相应内容。行号可以是 “数字”,在这一行之后新增,也可以是 “起始行,终止行”,在其中的每一行后新增。当不写行号时,在每一行之后新增。使用 $ 表示最后一行。后面的命令同理。
  • <行号>c<内容> :取代。用内容取代相应行的文本。
  • <行号>i<内容> :插入。在当前行的上面插入一行文本。
  • <行号>d :删除当前行的内容。
  • <行号>p :输出选择的内容。通常与选项 -n 一起使用。
  • s/<re>/<string>/ :将 <re>(正则表达式)匹配的内容替换为 < string>。

# 实用示例

  • sed -n '3p' my.txt
    # 输出 my.txt 的第三行
    sed '2d' my.txt
    # 删除 my.txt 文件的第二行
    sed '2,$d' my.txt
    # 删除 my.txt 文件的第二行到最后一行
    sed 's/str1/str2/g' my.txt
    # 在整行范围内把 str1 替换为 str2。
    # 如果没有 g 标记,则只有每行第一个匹配的 str1 被替换成 str2
    sed -e '4astr ' -e 's/str/aaa/' my.txt
    # -e 选项允许在同一行里执行多条命令。例子的第一条是第四行后添加一个 str,
    # 第二个命令是将 str 替换为 aaa。命令的执行顺序对结果有影响。

    注意,以上的例子并不会真正修改 my.txt 中的内容。若想修改,需要添加 -i 选项

  • src.txt 的第 2、4、8、16、32 行的内容提取到 result.txt 中:

    sed -n '2p;4p;8p;16p;' src.txt > result.txt

# awk

awk 是最复杂的剑客,它不仅仅是工具软件,还是一种微型编程语言。它逐行读取输入文件(或标准输入),根据分隔符,将该行划分成各个字段(列),存入 $1$2$3 ・・・・中去。然后按指定的规则处理并输出结果。

# 基础语法

awk [option] 'pattern { action }' file

# 参数说明

  • options :是一些选项,用于控制 awk 的行为。
  • pattern :是用于匹配输入数据的模式,如 \regex\NR == 1BEGIN (在文件处理前)、 END (在文件处理后)。如果省略,则 awk 将对所有行进行操作。
  • {action} :是在匹配到模式的行上执行的动作。如果省略,则默认动作是打印( print )整行。

# 常用内置变量

变量说明
$0当前整行内容
$1, $2, ..., $N第 1, 2, ..., N 列(默认以空格或制表符分隔)
NF当前行的列数
NR当前行号
FS输入字段分隔符(默认空格)
OFS输出字段分隔符(默认空格)
FILENAME当前处理的文件名

# 自定义变量

有两种方式:

  • -v var=value (区分字符的大小写)

    awk -v test='hello' 'BEGIN {print test}'

  • { action } 中定义

    awk 'BEGIN {test='hello' print test}'

# 实用实例

  • 打印整行:

    awk '{print}' file
  • 打印特定列:

    awk '{print $1, $2}' file
  • 使用分隔符指定列:

    awk -F',' '{print $1, $2}' file
  • 打印行数:

    awk '{print NR, $0}' file
  • 打印行数满足条件的行:

    awk '/pattern/ {print NR, $0}' file
  • 计算列的总和:

    awk '{sum += $1} END {print sum}' file
  • 打印最大值:

    awk 'max < $1 {max = $1} END {print max}' file
  • 格式化输出:

    awk '{printf "%-10s %-10s\n", $1, $2}' file

# Lab0 实践

  • sed :image-20250313160725790image-20250313160740518

    #!/bin/bash
    # 获取输入参数
    SOURCE_FILE=$1
    TARGET_FILE=$2
    # 提取指定行的内容并写入目标文件
    sed -n '8p;32p;128p;512p;1024p' "$SOURCE_FILE" > "$TARGET_FILE"
  • sedawk :

    image-20250313160920400

    #!/bin/bash
    pattern=$2
    sed -n "/$pattern/=" $1 > $3
    #!/bin/bash
    filea=$1
    pattern=$2
    fileb=$3
    awk -v pat="$pattern" 'index($0, pat) {print NR}' "$filea" > "$fileb"
  • sed :

    image-20250313162423931

    #!/bin/bash
    FILE=$1
    SRC=$2
    DST=$3
    sed -i "s/$SRC/$DST/g" "$FILE"

# 参考资料

whisper_hm - 博客园

三剑客 - CSDN 博客

菜鸟教程

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

CircleCoder 微信支付

微信支付

CircleCoder 支付宝

支付宝

CircleCoder 贝宝

贝宝