玩转linux三剑客-grep sed awk学习-入门篇

本文深入讲解Linux下文本处理的三大利器:grep用于查找,sed擅长替换,awk则专于切片及数据分析。文章详细介绍了它们的功能、使用场景及常见命令,适合初学者和进阶用户学习掌握。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

三剑客有 awk,sed,grep。三剑客结合正则表达式来使用。

grep 查找,sed 替换,awk 切片

grep 擅长正则查找行,sed 擅长替换,awk 擅长取列并且理论上可以替代 grep,awk 除了我们这里介绍的一些命令,awk 其实它本身就是一门解释型编程语言

三剑客之正则

下面为三剑客都通用的正则,有基础正则和扩展正则,其中 grep 和 sed 需要加上-E才能使用扩展正则,若不使用-E对扩展正则中的特殊字符加上\进行转义也行。awk 倒是很方便,不用加-E直接使用上面扩展正则

  • 基础正则中提供^$.*[]这些元字符

  • 扩展正则中则包含ERE: ^$.*[]+(){}?|这些元字符,比基础正则多出了+(){}?|这些元字符

#【基本正则 BRE】
# 以什么开头,a 打头
^
^a
# 以什么结尾,a 结尾
$
$a
# 表示空行
^$
# 表示任一个字符
.
# 表示区间,匹配到含有任意一个 a c d,匹配所有数字,匹配所有大小写字母
[]
[acd]
[0-9]
[a-Z]
# 表示反向字符集,[^abc] 指的是不为 a b c 中的任意一个的字符,若有一行中只有 a b c 中的一个或多个,该行就不会被抓取到,若该行有 a b c d,那么该行会被抓取到,因为该行中除了 a b c 之外还有一个 d 字符
[^abc]
# 表示匹配前一个字符可出现 0 个或多个,a 出现 0 次或多次
*
ba*

#【拓展正则 ERE】
# 上一个字符 a 出现或没有出现
?
ba?
# 匹配前一个字母出现一个或多个,匹配 a 出现一个或多个
+
ba+
# 分组匹配,小括号中是一个整体
()
te(s|x)t
# 范围约束,匹配 a 最少 1 次,最多连续出现 5 次,如 a,aa,aaa,aaaa,aaaaa
{}
n{1,5}
# 匹配多个表达式的任何一个,匹配 e 或 l
|
e|l

grep(global regular expression print 全局正则表达式打印)

  • 功能

    查找

    文本过滤工具

    擅长基于正则表达式查找满足条件的行

  • 写法

    grep options 'pattern' file

  • options

    # 显示匹配的行号
    -n
    # 显示未匹配到的行
    -v
    # 忽略大小写去匹配行
    -i
    # 把每个匹配内容用独立行显示,会将匹配到行中的无关字段隐藏
    -o
    # 表示输出符合样式的行的次数
    -c
    # 有很多匹配的只输出前面多少个
    -m 数字
    # 使用扩展正则表达式,要是懒得加 -E 直接使用 egrep 算了
    -E
    # 打印匹配行后几行
    -A 数字
    # 打印匹配行前几行
    -B 数字
    # 打印匹配行前后各几行
    -C 数字
    # 递归搜索
    grep pattern -r dir/
    
  • pattern 正则(也是三剑客都可适用的正则)

    #【基本正则 BRE】
    # 以什么开头
    ^
    # 以什么结尾
    $
    # 表示区间
    [a-z]
    # 表示区间
    [0-9]
    # 表示 0 个或多个
    *
    
    #【拓展正则 ERE】
    # 非贪婪匹配
    ?
    # 匹配一个或多个
    +
    # 分组匹配
    ()
    # 范围约束
    {}
    # 匹配多个表达式的任何一个
    |
    
  • 举例

    # 某一文件中查找 export 字段并且显示行号
    grep -n 'export' /etc/profile
    # 查找以 e 打头的行并显示行号
    grep -n '^e' /etc/profile
    # 查找以 e 开头的前两行就行了
    grep -m '^e' /etc/profile
    # 查找以 e 结尾的行并显示行号
    grep -n 'e$' /etc/profile
    # E 代表后面可以接扩展正则表达式
    grep -E 'java|python' /etc/profile
    # 忽略大小写匹配
    grep -i 'Export' /etc/profile
    # 显示匹配之外的行
    grep -v 'export' /etc/profile
    # 把每个匹配的内容用独立的行显示
    grep -o 'export' /etc/profile
    

sed(stream editor 流编辑器)

  • 功能

    替换

    流编辑器,一次处理一行内容,处理时候把当前处理的行存储在缓冲区,叫做“模式空间”,接着 sed 命令开始处理缓冲区内容,处理完后,把缓冲区内容送往屏幕上送,再读入下一行,循环。

    注意:sed 替换了字符其实并没有改变源文件,只是自己另外开出了一个模式空间,除非加上 i 表示更改了源文件,注意对源文件进行备份

    擅长根据定位到的数据进行修改替换数据

  • 写法

    sed [options] [script] [file]

  • options

    # 不输出模式空间内容到屏幕,即正常打印
    -n
    # 直接编辑修改源文件
    -i
    # 可多次编辑
    -e
    # 扩展表达式
    -E
    # 调试
    --debug
    
  • script

    # 第几个模式空间的内容
    p
    # 删除匹配到 xxx 的行,/.../ 中写正则匹配的字串
    /xxx/d
    # 表示只替换第一个匹配到的字符串
    s/原元素,可直接正则写/被替换成的元素,可直接正则写/g
    # 表示替换所有匹配到的
    s/.../.../g
    # 删除
    d
    
  • 举例

    # 打印文件第三行
    sed -n '3p' /etc/profile
    # 打印三到五行
    sed -n '3,5p' /etc/profile
    # 删除第二行
    sed '2d' /etc/profile
    # 删除二到五行
    sed '2,5d' /etc/profile
    # 删除二到最后一行
    sed '2,$d' /etc/profile
    # 将文中每一行中第一下找到的 a 替换成 b,注意是每一行,i 表示直接在源文件中修改
    sed -i 's/a/b/' /file/myfile
    # 将文件中 a 全部替换成 b
    sed -i 's/a/b/g' /file/myfile
    # 多次编辑,不加 e 一次编辑,加 e 可多次编辑
    sed -e 's/a/b/g' -e 's/b/c/g' /file/myfile
    

awk(Alfred Aho,Peter Weinberger,Brian Kernighan 三人姓氏首字母)

  • 功能

    切片

    报告生成器,一种语言解析引擎,其具备完备的变成特性,格式化文本取列。awk 理论上可以代替 grep

    简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,awk每接收文件的一行,然后执行相应的命令,来处理文本,对于日志,CSV 这样每行格式相同的文本,awk 可以很方便的处理

    awk 其实不仅仅是工具了,还是一种编程语言,我们这里讲它的命令形式

    擅长替换列,理论上可以代替 grep,在对数据分析生成报告上功能强大

  • 写法

    awk 'parttern' filename

    awk '{action}' filename

    awk 'parttern {action}' filename

  • script

    美元符在 awk 中是特殊符号

    # 指定分隔符,后跟分隔符
    -F
    # 打印
    print
    # 当前一整行
    $0
    # 第一列段
    $1
    # 最后一段
    $NF
    # 倒数第二段
    $(NF-1)
    # 当前行号
    $NR
    # 取第二行
    NR==2
    # 正则匹配
    /xxx/
    # 正则匹配以什么开头
    /^xxx/
    # 正则没有匹配到什么
    !/xxx/
    # 字段匹配,从第二个字段开始匹配包含 xxx 的行,波浪线表示后面是正则语法
    $2~/xxx/
    # 字段匹配,从第二个字段开始匹配没有 xxx 的行
    $2!~/xxx/
    # 这里也可以表示分隔符,与 -F '...' 同
    BEGIN{FS="..."}
    
  • 举例

    awk 在使用正则的时候可是要加 /xxx/ 这样的形式,awk 中如果是用到 if,print 这样程序设计语言中的关键字的脚本时候需要加上大括号 {}

    # 等同于 cat 查看
    awk '{print}' file
    awk '{print $0}' file
    # 表示存在第一列段的行
    awk '$1' file
    # 表示第一列段是 aaa 的行
    awk '$1=="aaa"' file
    # 以 ; 或者空格作为分隔符而不是默认的空格作为分隔符
    awk -F '[; ]' '{print $2}' file
    # 打印报表,前面输出,后面输出,注意这里可以插入'\t'表示 tab 从而使得报表列是对其的
    awk 'BEGIN{print 'column1', 'column2'} {print $1, $2} END{print 'end1', 'end2'}' file
    # 输出奇数的行
    awk 'NR % 2 == 1 {print $0}' file
    # 输出第 2 行以后的行
    awk 'NR > 2 {print $0}' file
    # 文档中如果第 9 列是 200 输出 success,如果是非 200 输出 error
    awk '{if ( $1 == "200" ) print "success"; else print "error"}' file
    # 把当前行打印出来,$0 代表当前行,print 是打印命令,这里打印出 Hello World!
    echo 'Hello World!' | awk '{print $0}'
    # awk 会根据空格或者制表符把一行分段,$0 代表当前行,$1 表示第一段,$2 表示第二  段,这里打印出 Hello
    echo 'Hello World!' | awk '{print $1}'
    # 根据分隔符来分割,最后输出每一行中分割后满足条件的那一段,这里打印出 Hell
    echo 'Hello World!' | awk -F 'o' '{print $1}'
    # NF 变量表示当前有多少个字段,因此 $NF 实际表示最后一个字段,这里打印出 World!
    echo 'Hello World!' | awk '{print $NF}'
    # NF-1 表示倒数第二个字段,这里打印出 Hello
    echo 'Hello World!' | awk '{print $(NF-1)}'
    # 逗号表示输出时两部分之间使用空格分开,下面打印出 W rld!
    echo 'Hello World!' | awk '{print $1, $NF}'
    # 要原样打印字符需要加上双引号,NR 表示当前行号,如下打印出 1) is Hell
    echo 'Hello World!' | awk '{print $NR "," $1}'
    
### Awk 使用指南 Awk 是一种强大的文本处理工具,能够高效地完成复杂的文本过滤、分析和转换任务。以下是关于如何使用 awk 的详细介绍以及一些实用的示例。 #### 1. 基础语法 Awk 支持多种调用方式,具体如下: - **命令行方式** 在命令行中直接运行 awk 脚本,适用于简单的操作场景。其基本形式为: ```bash awk [-F field-separator] 'commands' input-file(s) ``` 其中 `commands` 表示具体的 awk 处理逻辑,`field-separator` 定义字段分隔符(默认为空白字符)。例如: ```bash awk '{print $1, $2}' data.txt ``` 上述命令会打印文件 `data.txt` 中每行的第一个和第二个字段[^2]。 - **Shell 脚本方式** 将所有 awk 命令写入一个独立的脚本文件,并设置该文件为可执行文件。脚本的第一行为解释器路径声明,类似于 Shell 脚本的方式: ```bash #!/usr/bin/awk -f { print "Line:", NR, ", Field Count:", NF } ``` 执行此脚本时可以直接通过脚本名传递参数或输入文件[^2]。 - **外部脚本方式** 如果需要频繁重用某些复杂逻辑,可以将这些逻辑保存到单独的 `.awk` 文件中并通过 `-f` 参数引入: ```bash awk -f script.awk input.txt ``` #### 2. 实际应用案例 ##### (1) 过滤特定模式的数据 假设有一个 `/etc/passwd` 文件,我们希望提取其中用户名以字母开头的所有条目: ```bash awk -F':' '$1 ~ /^[a-zA-Z]/ {print $1}' /etc/passwd ``` 这里设置了自定义字段分隔符 `:` 并利用正则表达式筛选符合条件的内容[^1]。 ##### (2) 统计数值总和 对于包含列向量数据的情况,比如统计某日志文件中第二列表示的数量总计: ```bash awk '{sum += $2} END{print "Total Sum:", sum}' log_file.log ``` 上述代码片段展示了如何累加指定位置上的整数并最终输出结果[^3]。 ##### (3) 错误检测与时间戳解析 当面对可能存在异常记录的日志源时,可以通过条件判断排除非法项后再做进一步加工。例如验证时间戳合法性的同时尝试将其转化为更易读的形式: ```bash @include "timeconv.awk" { if ($1 ~ /^[0-9]+$/) { timestamp = convert_to_human_readable($1); printf("Valid Timestamp: %s\n", timestamp); } else { printf("Invalid Entry Found At Line:%d Value=%s\n", NR, $1); } } ``` 这段伪代码演示了结合库函数实现高级功能的可能性[^4]。 #### 3. 高级特性概览 除了基础的功能外,awk 提供了许多增强型特性和内置变量支持更加灵活的操作需求,如: - **BEGIN 和 END 块**: 分别用于初始化阶段及结束后的清理工作; - **数组结构**: 方便存储临时中间状态或者构建映射关系; - **控制流语句**: 类似 C/C++ 的循环、分支机制允许编写更为精细的行为描述; --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值