grep工具

grep是过滤工具;用于根据关键字进行行过滤

语法:

1
# grep [选项] '关键字' 文件名

常见选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
OPTIONS:
-i: 不区分大小写
-v: 查找不包含指定内容的行,反向选择
-w: 按单词搜索
-o: 打印匹配关键字
-c: 统计匹配到的行数
-n: 显示行号
-r: 逐层遍历目录查找
-A: 显示匹配行及后面多少行
-B: 显示匹配行及前面多少行
-C: 显示匹配行前后多少行
-l:只列出匹配的文件名
-L:列出不匹配的文件名
-e: 使用正则匹配
-E:使用扩展正则匹配
^key:以关键字开头
key$:以关键字结尾
^$:匹配空行
--color=auto :可以将找到的关键词部分加上颜色的显示

颜色显示(别名设置):

centos 7 之后都默认自带的

1
2
3
4
5
6
7
8
9
10
11
临时设置:
# alias grep='grep --color=auto' //只针对当前终端和当前用户生效
永久设置:
1)全局(针对所有用户生效)
vim /etc/bashrc
alias grep='grep --color=auto'
source /etc/bashrc
2)局部(针对具体的某个用户)
vim ~/.bashrc
alias grep='grep --color=auto'
source ~/.bashrc

举例说明:
说明:不要直接使用/etc/passwd文件,将其拷贝到/tmp下做实验!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# grep -i root passwd                        忽略大小写匹配包含root的行
# grep -w ftp passwd 精确匹配ftp单词
# grep -w hello passwd 精确匹配hello单词;自己添加包含hello的行到文件
# grep -wo ftp passwd 打印匹配到的关键字ftp
# grep -n root passwd 打印匹配到root关键字的行好
# grep -ni root passwd 忽略大小写匹配统计包含关键字root的行
# grep -nic root passwd 忽略大小写匹配统计包含关键字root的行数
# grep -i ^root passwd 忽略大小写匹配以root开头的行
# grep bash$ passwd 匹配以bash结尾的行
# grep -n ^$ passwd 匹配空行并打印行号
# grep ^# /etc/vsftpd/vsftpd.conf 匹配以#号开头的行
# grep -v ^# /etc/vsftpd/vsftpd.conf 匹配不以#号开头的行
# grep -A 5 mail passwd 匹配包含mail关键字及其后5行
# grep -B 5 mail passwd 匹配包含mail关键字及其前5行
# grep -C 5 mail passwd 匹配包含mail关键字及其前后5行

sed工具

其主要功能为对文件进行修改处理,可以对文件或标准输入数据流进行增删改查等操作,尤其适用于大文件或有规律的文件

适用场景

  • 超大文件处理;
  • 有规律的文本,例如格式化后的日志文件等;
  • 对文件进行批量增加,替换等。

语法:

1
sed 选项 "地址界定 命令" 处理的文件

例子:
生成1到50的行的文件

1
seq 50  > test
  • 查询

    1
    2
    3
    4
    5
    6
    显示3和11行
    [root@localhost test]# sed -n '3p;11p' test
    显示3到11行
    [root@localhost test]# sed -n '3,11p' test
    显示最后一行(使用正则表达式)
    [root@localhost test]# sed -n '$p' test
  • 删除

    1
    2
    3
    4
    全部删除
    [root@localhost test]# sed 'd' test
    删除最后一行
    [root@localhost test]# sed '$d' test
  • 插入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    第10行上面插入xxxx     (i可以理解成infor)
    [root@localhost test]# sed '10i xxxx' test

    第10行下面插入xxxx (a可以理解成after)
    [root@localhost test]# sed '10a xxxx' test

    10到最后一行下面插入xxxx (a可以理解成after 这里用到了正则)
    [root@localhost test]# sed '10,$a xxxx' test

    把第10行的10,改成xxxxx (10s代表第用两个井号隔开)
    [root@localhost test]# sed '10s#10#xxxxx#' test

    5到10行行末尾插入xxxxx
    [root@localhost test]# sed '5,10s#$#xxxxx#' test

    提示!
    `-i.bak`先备份后执行,会多出一个文件xxx.bak
    [root@localhost test]# sed -i.bak '$d' test
  • sed的反向引用
    例子:批量重命名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    生成文件,目的将生成的文件改成hello_+数字.log
    [root@localhost mv]# touch hello_{10010..10030}_world.log

    测试:
    [root@localhost mv]# find . -type f -name '*.log' | sed -r 's#^(.*)_world(.*)#mv \0 \1\2#'

    解释:find:寻找文件名包含log的文件,sed用正则匹配语句\0代表完整的名称,\1\2代表两个括号匹配的内容。

    mv ./hello_10010_world.log ./hello_10010.log
    mv ./hello_10011_world.log ./hello_10011.log
    mv ./hello_10012_world.log ./hello_10012.log
    mv ./hello_10013_world.log ./hello_10013.log
    mv ./hello_10014_world.log ./hello_10014.log
    mv ./hello_10015_world.log ./hello_10015.log
    mv ./hello_10016_world.log ./hello_10016.log
    mv ./hello_10017_world.log ./hello_10017.log
    mv ./hello_10018_world.log ./hello_10018.log
    mv ./hello_10019_world.log ./hello_10019.log
    mv ./hello_10020_world.log ./hello_10020.log
    mv ./hello_10021_world.log ./hello_10021.log
    mv ./hello_10022_world.log ./hello_10022.log
    mv ./hello_10023_world.log ./hello_10023.log
    mv ./hello_10024_world.log ./hello_10024.log
    mv ./hello_10025_world.log ./hello_10025.log
    mv ./hello_10026_world.log ./hello_10026.log
    mv ./hello_10027_world.log ./hello_10027.log
    mv ./hello_10028_world.log ./hello_10028.log
    mv ./hello_10029_world.log ./hello_10029.log
    mv ./hello_10030_world.log ./hello_10030.log

    -----分割线-----
    以上正是我们需要使用到的语句,最后添加管道符号让bash执行
    [root@localhost mv]# find . -type f -name '*.log' | sed -r 's#^(.*)_world(.*)#mv \0 \1\2#' | bash

    ll查看,完成

awk 工具

它更偏向于对文本的格式化处理输出,它不仅仅是一款工具,也是一门解释性语言

awksed命令类似,只不过sed擅长取行,awk命令擅长取列,awk是对文本进行格式化输出,sed更倾向于对文件进行修改;

用以下文本coins.txt作为实验

1
2
3
4
5
6
7
8
9
10
11
12
13
gold 1 1986 USA American Eagle
gold 1 1908 Austria-Hungary Franz josef 100 Korona
silver 10 1981 USA ingot
gold 1 1984 Switzerland ingot
gold 1 1979 RSA Krugerrand
gold 0.5 1981 RSA Krugerrand
gold 0.1 1986 PRC Panda
silver 1 1986 USA Liberty dollar
gold 0.25 1986 USA Liberty 5-dollar piece
silver 1 1986 USA Liberty 50-cent piece
silver 1 1987 USA Constitution dollar
gold 0.25 1987 USA Constitution 5-dollar piece
gold 1 1988 Canada Maple leaf

语法格式

1
awk {语句} 执行的文件

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
查看文本的前三列。\t 只是为了更美观显示
[root@localhost ~]# awk '{print $1 "\t" $2 "\t" $3}' coins.txt
gold 1 1986
gold 1 1908
silver 10 1981
gold 1 1984
gold 1 1979
gold 0.5 1981
gold 0.1 1986
silver 1 1986
gold 0.25 1986
silver 1 1986
silver 1 1987
gold 0.25 1987
gold 1 1988

----

NR是number of record;NF代表number of rield
(注意在awk中 空格 代表的是左边和右边的拼接起来,需要用逗号进行分隔符(或者制表符"\t")所以导致NF不准)

显示前三行和行号:
awk '{print NR "\t" $1 "\t" $2 "\t" $3}' coins.txt
1 gold 1 1986
2 gold 1 1908
3 silver 10 1981
4 gold 1 1984
5 gold 1 1979
6 gold 0.5 1981
7 gold 0.1 1986
8 silver 1 1986
9 gold 0.25 1986
10 silver 1 1986
11 silver 1 1987
12 gold 0.25 1987
13 gold 1 1988

-----

查找
查找1986年份的数据,可以把文本当作数据库。
[root@localhost ~]# awk '$3==1986{print $0}' coins.txt
gold 1 1986 USA American Eagle
gold 0.1 1986 PRC Panda
silver 1 1986 USA Liberty dollar
gold 0.25 1986 USA Liberty 5-dollar piece
silver 1 1986 USA Liberty 50-cent piece

更详细的链接:
http://www.imooc.com/wiki/shelllesson/awk.html
https://www.runoob.com/linux/linux-comm-awk.html

awk实在是太难用了,自我感觉操作列的话用cut反而更合适

cut工具

cut是截取工具,用于列的截取

语法和选项

语法:

1
# cut 选项  文件名

常见选项:

1
2
3
-c:    以字符为单位进行分割,截取
-d: 自定义分隔符,默认为制表符\t
-f: 与-d一起使用,指定截取哪个区域

举例说明:

1
2
3
4
5
6
# cut -d: -f1 1.txt             以:冒号分割,截取第1列内容
# cut -d: -f1,6,7 1.txt 以:冒号分割,截取第1,6,7列内容
# cut -c4 1.txt 截取文件中每行第4个字符
# cut -c1-4 1.txt 截取文件中每行的1-4个字符
# cut -c4-10 1.txt 截取文件中每行的4-10个字符
# cut -c5- 1.txt 从第5个字符开始截取后面所有字符
  • 例子
    用小工具列出你当系统的运行级别。5/3
  1. 如何查看系统运行级别
    1. 命令runlevel
    2. 文件/usr/lib/systemd/system/ctrl-alt-del.target
  2. 如何过滤运行级别
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    runlevel |cut -c3
    runlevel | cut -d ' ' -f2
    grep -v '^#' /etc/inittab | cut -d: -f2
    grep '^id' /etc/inittab |cut -d: -f2
    grep "initdefault:$" /etc/inittab | cut -c4
    grep -v ^# /etc/inittab |cut -c4
    grep 'id:' /etc/inittab |cut -d: -f2
    cut -d':' -f2 /etc/inittab |grep -v ^#
    cut -c4 /etc/inittab |tail -1
    cut -d: -f2 /etc/inittab |tail -1