Linux 三剑客(grep sed awk)学习

介绍

三剑客有 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
    # 使用扩展正则表达式,要是懒得加 -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 -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
    # 表示只替换第一个匹配到的字符串
    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
    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 的行,波浪线表示后面是正则语法
    $2~/xxx/
    # 字段匹配,从第二个字段开始匹配没有 xxx 的行
    $2!~/xxx/
    # 这里也可以表示分隔符,与 -F '...' 同
    BEGIN{FS="..."}
    
  • 举例

    # 表示存在第一列段的行
    awk '$1' file
    # 表示第一列段是 aaa 的行
    awk '$1=="aaa"' file
    # 以 ; 作为分隔符而不是默认的空格作为分隔符
    awk -F ';' '{print $2}' 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}'
    
发布了124 篇原创文章 · 获赞 40 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/abcnull/article/details/103874284