Shell Shell
Home
Shell
Linux
Network
Git
Blog (opens new window)
GitHub (opens new window)
Home
Shell
Linux
Network
Git
Blog (opens new window)
GitHub (opens new window)
  • Shell 脚本编程

    • 目录
    • 变量的高级用法
    • 函数的高级用法
    • 文件查找命令 find
    • 文本处理命令 grep
    • 文本处理命令 sed
      • sed 的工作模式
        • 基础介绍
        • 语法格式
      • sed 的选项
        • 选项
        • 测试
      • sed 中的 pattern 详解
        • 匹配模式
        • 测试
      • sed 中的编辑命令
        • 命令对照表
        • 测试 1
        • 反向引用
        • 测试 2
      • 利用 sed 查找文件内容
        • 查询命令对照表
        • 练习
      • 利用 sed 删除文件内容
        • 删除命令对照表
        • 练习
      • 利用 sed 修改文件内容
        • 修改命令对照表
        • 练习
      • 利用 sed 追加文件内容
        • 追加命令对照表
        • 示例详解
  • shell
  • Shell 脚本编程
JaimeZeng
2021-02-21

文本处理命令 sed

本章主要讲解 Shell 中最核心的文本处理三剑客之 sed 的用法。

# sed 的工作模式

# 基础介绍

  • sed(Stream Editor):流编辑器。对标准输出或文件逐行进行处理。

# 语法格式

格式
第一种 stdout | sed [option] "pattern command"
第二种 sed [option] "pattern command" file

# sed 的选项

# 选项

选项 含义
-n 只打印模式匹配行
-e 直接在命令行进行 sed 编辑,默认选项
-f 编辑动作保存在文件中,指定文件执行
-r 支持扩展正则表达式
-i 直接修改文件内容

# 测试

# 测试代码

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# sed 中的 option 练习

filepath=$(
    cd "$(dirname "$0")"
    pwd
)
testpath="${filepath}/test_dir"
filename="${testpath}/passwd"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function test_sed_option() {
    # 生成测试文件
    mkdir -p ${testpath} && cd ${testpath}
    cp /etc/passwd ./

    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中以 root 开始的行 ------${Font_color_suffix}\n" && sed -n '/^root/p' ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 zsh 或者 bash 的行 ------${Font_color_suffix}\n" && sed -n -e '/bash/p' -e '/zsh/p' ${filename}
    # 使用 -r 扩展正则表达式处理
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 zsh 或者 bash 的行(使用扩展正则表达式) ------${Font_color_suffix}\n" && sed -n -r '/bash|zsh/p' ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 root 的行 ------${Font_color_suffix}\n" && sed -n '/root/p' ${filename}

    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 /var/spool/mail 的行 ------${Font_color_suffix}\n" && sed -n '/\/var\/spool\/mail/p' ${filename}
    # 使用 -f 指定文件处理
    echo "/\/var\/spool\/mail/p" >>edit.sed
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 /var/spool/mail 的行(使用指定文件处理) ------${Font_color_suffix}\n" && sed -n -f edit.sed ${filename}

    # 使用 -i 直接修改文件内容
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 root 的行(sed) ------${Font_color_suffix}\n" && sed -n '/root/p' ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 root 的行(grep) ------${Font_color_suffix}\n" && grep -n 'root' ${filename}
    echo -e "\n${Green_font_prefix}------ 将 passwd 文件中的 root 替换为 jaime 并打印 ------${Font_color_suffix}\n" && sed -n 's/root/jaime/g;p' ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 jaime 的行(sed) ------${Font_color_suffix}\n" && sed -n '/jaime/p' ${filename}
    echo -e "\n${Green_font_prefix}------ 直接将 passwd 文件中的 root 替换为 jaime ------${Font_color_suffix}\n" && sed -i 's/root/jaime/g' ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 passwd 文件中包含 jaime 的行(grep) ------${Font_color_suffix}\n" && grep -n 'jaime' ${filename}

    # 删除测试目录
    cd ${filepath} && rm -rf test_dir/
    # rm -r passwd edit.sed
}

test_sed_option
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

# 运行结果

------ 打印 passwd 文件中以 root 开始的行 ------

root:x:0:0:root:/root:/bin/zsh

------ 打印 passwd 文件中包含 zsh 或者 bash 的行 ------

root:x:0:0:root:/root:/bin/zsh
ryan:x:1000:1000:ryan:/home/ryan:/bin/zsh

------ 打印 passwd 文件中包含 zsh 或者 bash 的行(使用扩展正则表达式) ------

root:x:0:0:root:/root:/bin/zsh
ryan:x:1000:1000:ryan:/home/ryan:/bin/zsh

------ 打印 passwd 文件中包含 root 的行 ------

root:x:0:0:root:/root:/bin/zsh
operator:x:11:0:operator:/root:/sbin/nologin

------ 打印 passwd 文件中包含 /var/spool/mail 的行 ------

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

------ 打印 passwd 文件中包含 /var/spool/mail 的行(使用指定文件处理) ------

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

------ 打印 passwd 文件中包含 root 的行(sed) ------

root:x:0:0:root:/root:/bin/zsh
operator:x:11:0:operator:/root:/sbin/nologin

------ 打印 passwd 文件中包含 root 的行(grep) ------

1:root:x:0:0:root:/root:/bin/zsh
10:operator:x:11:0:operator:/root:/sbin/nologin

------ 将 passwd 文件中的 root 替换为 jaime 并打印 ------

jaime:x:0:0:jaime:/jaime:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/jaime:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
ryan:x:1000:1000:ryan:/home/ryan:/bin/zsh
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
gluster:x:997:993:GlusterFS daemons:/run/gluster:/sbin/nologin
libstoragemgmt:x:996:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
unbound:x:995:991:Unbound DNS resolver:/etc/unbound:/sbin/nologin
saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
saned:x:993:990:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
colord:x:992:988:User for colord:/var/lib/colord:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
geoclue:x:991:987:User for geoclue:/var/lib/geoclue:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
setroubleshoot:x:990:986::/var/lib/setroubleshoot:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sssd:x:989:983:User for sssd:/:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
nginx:x:987:981:Nginx web server:/var/lib/nginx:/sbin/nologin

------ 打印 passwd 文件中包含 jaime 的行(sed) ------


------ 直接将 passwd 文件中的 root 替换为 jaime ------


------ 打印 passwd 文件中包含 jaime 的行(grep) ------

1:jaime:x:0:0:jaime:/jaime:/bin/zsh
10:operator:x:11:0:operator:/jaime:/sbin/nologin

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

# sed 中的 pattern 详解

# 匹配模式

匹配模式 含义
10commmand 匹配到第 10 行
10,20command 匹配从第 10 行开始,到第 20 行结束
10,+5command 匹配从第 10 行开始,到第 16 行结束
/pattern1/command 匹配到 pattern1 的行
/patttern1,/pattern2/command 匹配从 pattern 的行开始,到 pattern2 的行结束
10,/pattern1/command 匹配从第 10 行开始,到匹配到 pattern1 的行结束
/pattern1/,10command 匹配到 pattern1 的行开始,到第 10 行结束

注意:

  • 匹配模式中存在变量时,建议使用双引号。sed -i "/${var1}/${var2}/g"
  • 需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号。sed -i '/'${var1}'/'${var2}'/g'
1. LineNumber: 指定行号

    sed -n "17p" file   # 打印 file 的第 17 行

2. StartLine, EndLine: 指定起始和结束行号

    sed -n "10, 20p" file   # 打印 file 的 第 10 - 20 行

3. StartLine,+N:指定起始行号,然后后面 N 行

    sed -n "10, +5p" file   # 打印 file 的 第 10 - 16 行

4. /pattern1/: 正则表达式匹配的行

    sed -n "/^root/p" file  # 打印 file 文件中以 root 开始的行

5. /pattern1/,/pattern2/: 从匹配到 pattern1 的行,到匹配到 pattern2 的行

    sed -n /^mail/,/^ftp/p" file    # 打印 file 文件中从 mail 开始的行到 ftp 开始的行

6. LineNumber,/pattern1/: 从指定行开始匹配,匹配到 pattern1 的行结束

    sed -n "4,/shutdown$/p" file    # 打印 file 文件中从第 4 行到以 shutdown
    结束的行

7. /pattern1/,LineNumber: 从匹配到 pattern1 的行开始到指定行结束

    sed -n "/^bin/,6p" file     # 打印 file 文件中从以 bin 开始的行到 第 6 行
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

# 测试

# 测试代码

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

#  sed 中的 pattern 练习

filename='/etc/passwd'
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function test_sed_pattern() {
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 的第 3 行 ------${Font_color_suffix}\n" && sed -n "3p" ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 的第 1 - 5 行 ------${Font_color_suffix}\n" && sed -n "1, 5p" ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 的第 1 ,+5 行 ------${Font_color_suffix}\n" && sed -n "1, +5p" ${filename}

    # 正则表达式
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中以 root 开始的行 ------${Font_color_suffix}\n" && sed -n "/^root/p" ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中从 mail 开始的行到 ftp 开始的行 ------${Font_color_suffix}\n" && sed -n "/^mail/,/^ftp/p" ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中从第 4 行到以 shutdown 结束的行 ------${Font_color_suffix}\n" && sed -n "4,/shutdown$/p" ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中从以 bin 开始的行到第 6 行 ------${Font_color_suffix}\n" && sed -n "/^bin/,6p" ${filename}
    # 正则表达式转义
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中包含 /var/spool/mail 的行 ------${Font_color_suffix}\n" && sed -n "/\/var\/spool\/mail/p" ${filename}
    # 扩展正则表达式
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中包含 bash 或者 zsh 的行 ------${Font_color_suffix}\n" && sed -n -r "/bash|zsh/p" ${filename}

    # 如果起始行号 > 终止行号,只会显示起始行号的那一行
    echo -e "\n${Green_font_prefix}------ 在 /etc/passwd 中从包含 sshd 的行并显示行号 ------${Font_color_suffix}\n" && grep -n "sshd" ${filename}
    echo -e "\n${Green_font_prefix}------ 打印 /etc/passwd 中从包含 sshd 的行到第 6 行 ------${Font_color_suffix}\n" && sed -n "/sshd/,6p" ${filename}

}

test_sed_pattern
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

# 运行结果

------ 打印 /etc/passwd 的第 3 行 ------

daemon:x:2:2:daemon:/sbin:/sbin/nologin

------ 打印 /etc/passwd 的第 1 - 5 行 ------

root:x:0:0:root:/root:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

------ 打印 /etc/passwd 的第 1 ,+5 行 ------

root:x:0:0:root:/root:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

------ 打印 /etc/passwd 中以 root 开始的行 ------

root:x:0:0:root:/root:/bin/zsh

------ 打印 /etc/passwd 中从 mail 开始的行到 ftp 开始的行 ------

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

------ 打印 /etc/passwd 中从第 4 行到以 shutdown 结束的行 ------

adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

------ 打印 /etc/passwd 中从以 bin 开始的行到第 6 行 ------

bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

------ 打印 /etc/passwd 中包含 /var/spool/mail 的行 ------

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

------ 打印 /etc/passwd 中包含 bash 或者 zsh 的行 ------

root:x:0:0:root:/root:/bin/zsh
ryan:x:1000:1000:ryan:/home/ryan:/bin/zsh

------ 在 /etc/passwd 中从包含 sshd 的行并显示行号 ------

17:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

------ 打印 /etc/passwd 中从包含 sshd 的行到第 6 行 ------

sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# sed 中的编辑命令

# 命令对照表

类别 编辑命令 含义
查询 p 打印
增加 1 a 行后追加
增加 2 i 行前增加
增加 3 r 外部文件读入,行后追加
增加 4 w 匹配行写入外部文件
删除 d 删除
修改 1 s/old/new 将第一个 old 替换为 new
修改 2 s/old/new/g 将全部的 old 替换为 new
修改 3 s/old/new/2g 将第两个开始的所有的 old 替换为 new
修改 4 s/old/new/ig 将全部的 old 替换为 new ,忽略大小写

# 测试 1

# 测试代码

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# sed 中的 command 练习

filepath=$(
    cd "$(dirname "$0")"
    pwd
)
testpath="${filepath}/test_dir"
filename="${testpath}/passwd"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function test_sed_command() {
    mkdir -p ${testpath} && cd ${testpath}

    # 删除一行 delete
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 删除 passwd 文件中一行 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 删除 passwd 文件中的第 1 行 ...${Font_color_suffix}" && sed -n '1d' ${filename}
    echo -e "${Green_font_prefix} 直接删除前打印 passwd 的第 1 行 ...${Font_color_suffix}" && sed -n "1p" ${filename}
    echo -e "${Green_font_prefix} 直接删除 passwd 文件中的第 1 行 ... ${Font_color_suffix}" && sed -i '1d' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 的第 1 行 ...${Font_color_suffix}" && sed -n "1p" ${filename}

    # 删除多行 1
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 删除 passwd 文件中多行 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 直接删除前打印 passwd 的第 1 - 3 行 ...${Font_color_suffix}" && sed -n "1,3p" ${filename}
    echo -e "${Green_font_prefix} 直接删除 passwd 文件中的第 1 - 3 行 ... ${Font_color_suffix}" && sed -i '1,3d' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 的第 1 - 3 行 ...${Font_color_suffix}" && sed -n "1,3p" ${filename}

    # 删除多行 2
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 删除 passwd 文件中多行 2 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 直接删除前打印 passwd 中包含 /sbin/nologin 的行 ...${Font_color_suffix}" && sed -n '/\/sbin\/nologin/p' ${filename}
    echo -e "${Green_font_prefix} 直接删除 passwd 中包含 /sbin/nologin 的行 ... ${Font_color_suffix}" && sed -i '/\/sbin\/nologin/d' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 中包含 /sbin/nologin 的行 ...${Font_color_suffix}" && sed -n '/\/sbin\/nologin/p' ${filename}

    # 删除多行 3
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 删除 passwd 文件中多行 3 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 直接删除前打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...${Font_color_suffix}" && sed -n '/^mail/,/^ftp/p' ${filename}
    echo -e "${Green_font_prefix} 直接删除 passwd 中从 mail 开始的行到 ftp 开始的行 ... ${Font_color_suffix}" && sed -i '/^mail/,/^ftp/d' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...${Font_color_suffix}" && sed -n '/^mail/,/^ftp/p' ${filename}

    # 行后追加内容 append
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ passwd 文件行后追加内容 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 直接追加前打印 passwd 中包含 root:/root 的行 ...${Font_color_suffix}" && sed -n '/root:\/root/p' ${filename}
    echo -e "${Green_font_prefix} 直接在 passwd 中包含 root:/root 的行后追加 This is user which can login system ...${Font_color_suffix}" && sed -i '/root:\/root/a This is user which can login system' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 中 1 - 3 行 ...${Font_color_suffix}" && sed -n "1,3p" ${filename}

    # 行前插入内容 insert
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ passwd 文件行前插入内容 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...${Font_color_suffix}" && sed -n '/^mail/,/^ftp/p' ${filename}
    echo -e "${Green_font_prefix} 直接在 passwd 中从 mail 开始的行到 ftp 开始的行前添加 This is nologin user  ...${Font_color_suffix}" && sed -i '/^mail/,/^ftp/i This is nologin user' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...${Font_color_suffix}" && sed -n '/^mail/,/^ftp/p' ${filename}

    # 将指定文件内容追加到匹配行后 rewrite
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ passwd 文件中添加指定文件的内容 ------${Font_color_suffix}\n"
    echo "This is user which can login system" >>rewrite
    echo -e "${Green_font_prefix} 直接追加前打印 passwd 中包含 root:/root 的行 ...${Font_color_suffix}" && sed -n '/root:\/root/p' ${filename}
    echo -e "${Green_font_prefix} 直接在 passwd 中包含 root:/root 的行后追加 rewrite 文件内容 ...${Font_color_suffix}" && sed -i '/root:\/root/r rewrite' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 中 1 - 3 行 ...${Font_color_suffix}" && sed -n "1,3p" ${filename}

    # 将匹配到的行内容保存到其它文件 write
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ passwd 文件中的内容追加到指定文件中 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 直接追加前打印 passwd 中包含 root:/root 的行 ...${Font_color_suffix}" && sed -n '/root:\/root/p' ${filename}
    echo -e "${Green_font_prefix} 直接将 passwd 中包含 root:/root 的行内容保存到 write 文件中 ...${Font_color_suffix}" && sed -i '/root:\/root/w write' ${filename}
    echo -e "${Green_font_prefix} 打印 write 文件 ...${Font_color_suffix}" && cat -n write

    # 替换第一个
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 替换 passwd 中第一个 root 为 jaime ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 root 的行(grep) ...${Font_color_suffix}" && grep -n 'root' ${filename}
    echo -e "${Green_font_prefix} 直接将 passwd 文件中的第一个 root 替换为 jaime ...${Font_color_suffix}" && sed -i 's/root/jaime/g' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 jaime 的行(grep) ...${Font_color_suffix}" && grep -n 'jaime' ${filename}

    # 替换第二个开始的所有的 root
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 替换 passwd 中从第二个开始的所有的 root 为 jaime ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 root 的行(grep) ...${Font_color_suffix}" && grep -n 'root' ${filename}
    echo -e "${Green_font_prefix} 直接将 passwd 文件中从第二个开始的所有的 root 为 jaime ...${Font_color_suffix}" && sed -i 's/root/jaime/g' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 jaime 的行(grep) ...${Font_color_suffix}" && grep -n 'jaime' ${filename}

    # 替换所有的 root
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 替换 passwd 中所有的 root 为 jaime ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 root 的行(grep) ...${Font_color_suffix}" && grep -n 'root' ${filename}
    echo -e "${Green_font_prefix} 直接将 passwd 文件中的所有的 root 替换为 jaime ...${Font_color_suffix}" && sed -i 's/root/jaime/g' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 jaime 的行(grep) ...${Font_color_suffix}" && grep -n 'jaime' ${filename}

    # 替换所有的 ssh
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 替换 passwd 中所有的 ssh|SSH 为 http ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 ssh|SSH 的行(grep) ...${Font_color_suffix}" && grep -n -E 'ssh|SSH' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 ssh|SSH 的行(sed) ...${Font_color_suffix}" && sed -n -r '/ssh|SSH/p' ${filename}
    echo -e "${Green_font_prefix} 直接将 passwd 文件中的所有的 ssh|SSH 替换为 jaime(不区分大小写) ...${Font_color_suffix}" && sed -i 's/ssh/http/ig' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 http 的行(grep) ...${Font_color_suffix}" && grep -n 'http' ${filename}

    # 显示行号
    rm -f passwd && cp -f /etc/passwd ./
    echo -e "\n${Red_font_prefix}------ 查找 passwd 文件中包含 zsh 或者 bash 的行并显示行号 ------${Font_color_suffix}\n"
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 zsh 或者 bash 的行并显示行号(使用 sed 扩展正则表达式) ...${Font_color_suffix}\n" && sed -n -r '/bash|zsh/=;p' ${filename}
    echo -e "${Green_font_prefix} 打印 passwd 文件中包含 zsh 或者 bash 的行并显示行号(grep) ...${Font_color_suffix}" && grep -n -E 'bash|zsh' ${filename}

    # 删除测试文件
    cd ${filepath} && rm -rf test_dir/

}
test_sed_command
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

# 运行结果

------ 删除 passwd 文件中一行 ------

 删除 passwd 文件中的第 1 行 ...
 直接删除前打印 passwd 的第 1 行 ...
root:x:0:0:root:/root:/bin/zsh
 直接删除 passwd 文件中的第 1 行 ...
 打印 passwd 的第 1 行 ...
bin:x:1:1:bin:/bin:/sbin/nologin

------ 删除 passwd 文件中多行 ------

 直接删除前打印 passwd 的第 1 - 3 行 ...
root:x:0:0:root:/root:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
 直接删除 passwd 文件中的第 1 - 3 行 ...
 打印 passwd 的第 1 - 3 行 ...
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

------ 删除 passwd 文件中多行 2 ------

 直接删除前打印 passwd 中包含 /sbin/nologin 的行 ...
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
gluster:x:997:993:GlusterFS daemons:/run/gluster:/sbin/nologin
libstoragemgmt:x:996:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
unbound:x:995:991:Unbound DNS resolver:/etc/unbound:/sbin/nologin
saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
saned:x:993:990:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
colord:x:992:988:User for colord:/var/lib/colord:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
geoclue:x:991:987:User for geoclue:/var/lib/geoclue:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
setroubleshoot:x:990:986::/var/lib/setroubleshoot:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sssd:x:989:983:User for sssd:/:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
nginx:x:987:981:Nginx web server:/var/lib/nginx:/sbin/nologin
 直接删除 passwd 中包含 /sbin/nologin 的行 ...
 打印 passwd 中包含 /sbin/nologin 的行 ...

------ 删除 passwd 文件中多行 3 ------

 直接删除前打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
 直接删除 passwd 中从 mail 开始的行到 ftp 开始的行 ...
 打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...

------ passwd 文件行后追加内容 ------

 直接追加前打印 passwd 中包含 root:/root 的行 ...
root:x:0:0:root:/root:/bin/zsh
 直接在 passwd 中包含 root:/root 的行后追加 This is user which can login system ...
 打印 passwd 中 1 - 3 行 ...
root:x:0:0:root:/root:/bin/zsh
This is user which can login system
bin:x:1:1:bin:/bin:/sbin/nologin

------ passwd 文件行前插入内容 ------

 打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
 直接在 passwd 中从 mail 开始的行到 ftp 开始的行前添加 This is nologin user  ...
 打印 passwd 中从 mail 开始的行到 ftp 开始的行 ...
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
This is nologin user
operator:x:11:0:operator:/root:/sbin/nologin
This is nologin user
games:x:12:100:games:/usr/games:/sbin/nologin
This is nologin user
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

------ passwd 文件中添加指定文件的内容 ------

 直接追加前打印 passwd 中包含 root:/root 的行 ...
root:x:0:0:root:/root:/bin/zsh
 直接在 passwd 中包含 root:/root 的行后追加 rewrite 文件内容 ...
 打印 passwd 中 1 - 3 行 ...
root:x:0:0:root:/root:/bin/zsh
This is user which can login system
bin:x:1:1:bin:/bin:/sbin/nologin

------ passwd 文件中的内容追加到指定文件中 ------

 直接追加前打印 passwd 中包含 root:/root 的行 ...
root:x:0:0:root:/root:/bin/zsh
 直接将 passwd 中包含 root:/root 的行内容保存到 write 文件中 ...
 打印 write 文件 ...
     1    root:x:0:0:root:/root:/bin/zsh

------ 替换 passwd 中第一个 root 为 jaime ------

 打印 passwd 文件中包含 root 的行(grep) ...
1:root:x:0:0:root:/root:/bin/zsh
10:operator:x:11:0:operator:/root:/sbin/nologin
 直接将 passwd 文件中的第一个 root 替换为 jaime ...
 打印 passwd 文件中包含 jaime 的行(grep) ...
1:jaime:x:0:0:root:/root:/bin/zsh
10:operator:x:11:0:operator:/jaime:/sbin/nologin

------ 替换 passwd 中从第二个开始的所有的 root 为 jaime ------

 打印 passwd 文件中包含 root 的行(grep) ...
1:root:x:0:0:root:/root:/bin/zsh
10:operator:x:11:0:operator:/root:/sbin/nologin
 直接将 passwd 文件中从第二个开始的所有的 root 为 jaime ...
 打印 passwd 文件中包含 jaime 的行(grep) ...
1:root:x:0:0:jaime:/jaime:/bin/zsh

------ 替换 passwd 中所有的 root 为 jaime ------

 打印 passwd 文件中包含 root 的行(grep) ...
1:root:x:0:0:root:/root:/bin/zsh
10:operator:x:11:0:operator:/root:/sbin/nologin
 直接将 passwd 文件中的所有的 root 替换为 jaime ...
 打印 passwd 文件中包含 jaime 的行(grep) ...
1:jaime:x:0:0:jaime:/jaime:/bin/zsh
10:operator:x:11:0:operator:/jaime:/sbin/nologin

------ 替换 passwd 中所有的 ssh|SSH 为 http ------

 打印 passwd 文件中包含 ssh|SSH 的行(grep) ...
17:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
 打印 passwd 文件中包含 ssh|SSH 的行(sed) ...
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
 直接将 passwd 文件中的所有的 ssh|SSH 替换为 jaime(不区分大小写) ...
 打印 passwd 文件中包含 http 的行(grep) ...
17:httpd:x:74:74:Privilege-separated http:/var/empty/httpd:/sbin/nologin

------ 查找 passwd 文件中包含 zsh 或者 bash 的行并显示行号 ------

 打印 passwd 文件中包含 zsh 或者 bash 的行并显示行号(使用 sed 扩展正则表达式) ...

1
root:x:0:0:root:/root:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
20
ryan:x:1000:1000:ryan:/home/ryan:/bin/zsh
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
gluster:x:997:993:GlusterFS daemons:/run/gluster:/sbin/nologin
libstoragemgmt:x:996:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
unbound:x:995:991:Unbound DNS resolver:/etc/unbound:/sbin/nologin
saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
saned:x:993:990:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
colord:x:992:988:User for colord:/var/lib/colord:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
geoclue:x:991:987:User for geoclue:/var/lib/geoclue:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
setroubleshoot:x:990:986::/var/lib/setroubleshoot:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sssd:x:989:983:User for sssd:/:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
nginx:x:987:981:Nginx web server:/var/lib/nginx:/sbin/nologin
 打印 passwd 文件中包含 zsh 或者 bash 的行并显示行号(grep) ...
1:root:x:0:0:root:/root:/bin/zsh
20:ryan:x:1000:1000:ryan:/home/ryan:/bin/zsh
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

# 反向引用

& 和 \1 引用模式匹配到的整个串。区别:

  • & 只能表示匹配到的完整字符串,只能引用整个字符串。
  • \1 可以使用 () 将匹配到的不需要改变的部分括起来,小括号需要转义。(例如:如果只需要替换匹配到的字符串的一部分,这是只能使用 \1 ,然后将不需要改变的部分用括号括起来,替换时只替换括号外的)

# 测试 2

# 需求描述

例如:有一个文件 str,内容如下。

hadAAp is a bigdata frame.
Spark hadBBp Kaffa.
Paper on hadCCp.
Google hadEEp.
1
2
3
4
  1. 将文件中的 hadAAp, hadBBp, ... hadEEp 后面加后缀 s。(hadAAp -> hadAAps, hadEEp -> hadEEps)
  2. 将上一步改变后的文件中的 hadAAps, hadBBps, ... hadEEps 后面加后缀 O 。(hadAAps -> hadAApsO, hadEEps -> hadEEpsO)
  3. 将上一步改变后的文件中的 hadAApsO, hadBBpsO, ... hadEEpsO 全部替换为 hadoop。
  4. 将上一步改变后的文件中的 hadoop 全部替换为 HADOOP。

# 思路分析

  1. 替换两种操作:

    $ sed -i 's/had..p/&s/g' str # had..p 表示匹配 hadAAp, hadBBp, ... hadEEp 字符串,& 引用 had..p 串
    $ sed -i 's/\(had..p\)/\1s/g' str # had..p 表示匹配 hadAAp, hadBBp, ... hadEEp 字符串,\1 引用 had..p 串
    
    1
    2
  2. 匹配模式中存在变量时,建议使用双引号。

# 代码编写

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# sed 中的 command 练习 2

filepath=$(
    cd "$(dirname "$0")"
    pwd
)
testpath="${filepath}/test_dir"
filename="${testpath}/str"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function sed_str() {
    # 生成测试文件
    mkdir -p ${testpath} && cd ${testpath}
    cat >>${filename} <<EOF
hadAAp is a bigdata frame.
Spark hadBBp Kaffa.
Paper on hadCCp.
Google hadEEp.
EOF
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    echo -e "${Red_font_prefix} 将 str 文件中的 hadAAp, hadBBp, ... hadEEp 后面加后缀 s ...${Font_color_suffix}" && sed -i 's/had..p/&s/g' ${filename}
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    echo -e "${Red_font_prefix} 将 str 文件中的 hadAAps, hadBBps, ... hadEEps 后面加后缀 O ...${Font_color_suffix}" && sed -i 's/\(had..ps\)/\1O/g' ${filename}
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    echo -e "${Red_font_prefix} 将 str 文件中的 hadAApsO, hadBBpsO, ... hadEEpsO 全部替换为 hadoop ...${Font_color_suffix}" && sed -i 's/\(had\)...../\1oop/g' ${filename}
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    old_str="hadoop"
    new_str="HADOOP"
    echo -e "${Red_font_prefix} 将 str 文件中的 hadoop 全部替换为 HADOOP(使用单引号操作,变量不加单引号) ...${Font_color_suffix}" && sed -i 's/${old_str}/${new_str}/g' ${filename}
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    sed -i "s/HADOOP/hadoop/g" ${filename}
    echo -e "${Red_font_prefix} 将 str 文件中的 hadoop 全部替换为 HADOOP(使用双引号操作) ...${Font_color_suffix}" && sed -i "s/${old_str}/${new_str}/g" ${filename}
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    sed -i "s/HADOOP/hadoop/g" ${filename}
    echo -e "${Red_font_prefix} 将 str 文件中的 hadoop 全部替换为 HADOOP(使用单引号操作,变量加单引号) ...${Font_color_suffix}" && sed -i 's/'${old_str}'/'${new_str}'/g' ${filename}
    echo -e "${Green_font_prefix} 打印 str 文件内容 ...${Font_color_suffix}" && cat -n ${filename}

    # 删除测试文件夹
    cd ${filepath} && rm -rf test_dir/
}

sed_str
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
48
49
50
51
52

# 脚本执行

 打印 str 文件内容 ...
     1    hadAAp is a bigdata frame.
     2    Spark hadBBp Kaffa.
     3    Paper on hadCCp.
     4    Google hadEEp.
 将 str 文件中的 hadAAp, hadBBp, ... hadEEp 后面加后缀 s ...
 打印 str 文件内容 ...
     1    hadAAps is a bigdata frame.
     2    Spark hadBBps Kaffa.
     3    Paper on hadCCps.
     4    Google hadEEps.
 将 str 文件中的 hadAAps, hadBBps, ... hadEEps 后面加后缀 O ...
 打印 str 文件内容 ...
     1    hadAApsO is a bigdata frame.
     2    Spark hadBBpsO Kaffa.
     3    Paper on hadCCpsO.
     4    Google hadEEpsO.
 将 str 文件中的 hadAApsO, hadBBpsO, ... hadEEpsO 全部替换为 hadoop ...
 打印 str 文件内容 ...
     1    hadoop is a bigdata frame.
     2    Spark hadoop Kaffa.
     3    Paper on hadoop.
     4    Google hadoop.
 将 str 文件中的 hadoop 全部替换为 HADOOP(使用单引号操作,变量不加单引号) ...
 打印 str 文件内容 ...
     1    hadoop is a bigdata frame.
     2    Spark hadoop Kaffa.
     3    Paper on hadoop.
     4    Google hadoop.
 将 str 文件中的 hadoop 全部替换为 HADOOP(使用双引号操作) ...
 打印 str 文件内容 ...
     1    HADOOP is a bigdata frame.
     2    Spark HADOOP Kaffa.
     3    Paper on HADOOP.
     4    Google HADOOP.
 将 str 文件中的 hadoop 全部替换为 HADOOP(使用单引号操作,变量加单引号) ...
 打印 str 文件内容 ...
     1    HADOOP is a bigdata frame.
     2    Spark HADOOP Kaffa.
     3    Paper on HADOOP.
     4    Google HADOOP.
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

# 利用 sed 查找文件内容

# 查询命令对照表

命令 含义
1p 打印第 1 行内容
1,10p 打印第 1 行到第 10 行内容
1,1+5p 打印第 1 行到第 6 行内容
/pattern1/p 打印包含 pattern1 的行内容
/patttern1/,/pattern2/p 打印从包含 pattern1 到 包含 pattern2 的行内容
/pattern1/,10p 打印从包含 patttern1 到第 10 行的内容
10,/pattern1/p 打印第 10 行到包含 pattern1 的行内容
1. 打印 /etc/passwd 文件中第 20 行内容

   sed -n '20p' /etc/passwd

2. 打印 /etc/passwd 文件中第 8 - 20 行内容

   sed -n '8, 20p' /etc/passwd

3. 打印 /etc/passwd 文件中第 8, +5 行内容

   sed -n '8, +5p' /etc/passwd

4. 打印 /etc/passwd 文件中包含 zsh 或者 bash 的行

   sed -n -e '/bash/p' -e '/zsh/p' /etc/passwd

5. 打印 /etc/passwd 文件中包含 zsh 或者 bash 的行(使用扩展正则表达式)

   sed -n -r '/bash|zsh/p' /etc/passwd

6. 打印 /etc/passwd 文件中包含 /var/spool/mail 的行

   sed -n '\/var\/spool\/mail' /etc/passwd

7. 打印 /etc/passwd 中以 root 开始的行

   sed -n '/^root/p' /etc/passwd

8. 打印 /etc/passwd 中从 mail 开始的行到 ftp 开始的行

   sed -n '/^mail/,/^ftp/p' /etc/passwd

9. 打印 /etc/passwd 中从第 4 行到以 shutdown 结束的行

   sed -n '4,/shutdown$/p' /etc/passwd

10. 打印 /etc/passwd 中从以 bin 开始的行到第 6 行

    sed -n '/^bin/,6p' /etc/passwd
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

# 练习

# 需求描述

处理一个类似 MySQL 配置文件 my.cnf 的文本,示例如下。

# this is read by the standalone daemon and embedded servers
[client]
port = 3306
socket = /tmp/mysql.socket

# this Segment Fot server
[server]
innodb_buffer_pool_size = 91750M
innodb_buffer_pool_instances = 8
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
innodb_max_undo_log_size = 4G
innodb_undo_directory = undolog
innodb_undo_tablespaces = 95

# this is only for the mysqld standalone daemon
[mysqld]
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir = /data/mysql
pid-file = /data/mysql/mysql.pid
user = mysql
bind-address = 0.0.0.0
sort_buffer_size = 16M
join_buffer_size = 16M
thread_cache_size = 3000
interactive_timeout = 600

# this Segment For mysqld safe
[mysqld safe]
log-error = /var/log/mariadb/mariadb.log
pid-file = /var/run/mariadb/mariadb.pid
max_connections = 1000
open_files_limit = 65535
thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M

# this is only for embedded server
[embedded]
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates
slave-rows-search-algorithms = 'INDEX_SCAN, HASH_SCAN'
binlog_format = row
binlog_checksum = 1
relay_log_recovery = 1
relay-log-purge = 1

# use this group for options that older servers don't understand
[mysqld-5.5]
key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

编写脚本实现以下功能:

  1. 输出文件有几个段;
  2. 针对每个段可以统计配置参数总个数。

预想输出结果:

第 1 个配置项:      client 共有  2 个配置项.
第 2 个配置项:      server 共有 12 个配置项.
第 3 个配置项:      mysqld 共有 11 个配置项.
第 4 个配置项: mysqld_safe 共有  7 个配置项.
第 5 个配置项:    embedded 共有  8 个配置项.
第 6 个配置项:  mysqld-5.5 共有  9 个配置项.

 ------ my.cnf 共有 6 个段. ------
1
2
3
4
5
6
7
8

# 思路分析

  1. function get_all_segment 获取所有段;

    • grep 直接获取 [client] 字符串 grep -E "^\[" ${filename}

    • sed 直接获取 [client] 字符串, 然后将 '[' ']' 替换为空 sed -n "/\[.*\]/p" ${filename} | sed -e "s/\[//g" -e "s/\]//g"

    • 直接使用 sed 反向引用获取 [client] 字符串内的 client 字段 sed -n -e "s/\[\(.*\)\]/\1/gp" ${filename}

  2. function count_items_in_segment 统计配置参数总个数;

    • grep:使用 sed "//,//p" 区间匹配, 然后排除 [client]、空行、注释行, 最后统计。 sed -n "/\["$1"\]/,/\[.*\]/p" ${filename} | grep -v "\[.*\]" | grep -v "^\#" | grep -v "^$" | wc -l)
    • sed:使用 sed "//,//p" 区间匹配, 然后排除 [client]、空行、注释行, 最后统计。$(sed -n "/\["$1"\]/,/\[.*\]/p" ${filename} | grep -v "\[.*\]" | grep -v "^\#" | grep -v "^$" | wc -l)

# 测试代码

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 处理 my.cnf 文件
# 1. function get_all_segment 输出文件有几个段;
# 2. function count_items_in_segment 针对每个段可以统计配置参数总个数。

filepath=$(
    cd "$(dirname "$0")"
    pwd
)
filename="${filepath}/my.cnf"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Blue_font_prefix="\033[34m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function create_my_cnf() {

    cat >${filename} <<EOF
# this is read by the standalone daemon and embedded servers
[client]
port = 3306
socket = /tmp/mysql.socket

# this Segment Fot server
[server]
innodb_buffer_pool_size = 91750M
innodb_buffer_pool_instances = 8
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
innodb_max_undo_log_size = 4G
innodb_undo_directory = undolog
innodb_undo_tablespaces = 95

# this is only for the mysqld standalone daemon
[mysqld]
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir = /data/mysql
pid-file = /data/mysql/mysql.pid
user = mysql
bind-address = 0.0.0.0
sort_buffer_size = 16M
join_buffer_size = 16M
thread_cache_size = 3000
interactive_timeout = 600

# this Segment For mysqld safe
[mysqld_safe]
log-error = /var/log/mariadb/mariadb.log
pid-file = /var/run/mariadb/mariadb.pid
max_connections = 1000
open_files_limit = 65535
thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M

# this is only for embedded server
[embedded]
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates
slave-rows-search-algorithms = 'INDEX_SCAN, HASH_SCAN'
binlog_format = row
binlog_checksum = 1
relay_log_recovery = 1
relay-log-purge = 1

# use this group for options that older servers don't understand
[mysqld-5.5]
key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1
EOF
}

function get_all_segment() {

    # grep 直接获取 [client] 字符串
    # grep -E "^\[" ${filename}

    # sed 直接获取 [client] 字符串, 然后将 '[' ']' 替换为空
    # sed -n "/\[.*\]/p" ${filename} | sed -e "s/\[//g" -e "s/\]//g"

    #直接使用 sed 反向引用获取 [client] 字符串内的 client 字段
    # sed -n -e "s/\[\(.*\)\]/\1/gp" ${filename}

    echo -e "$(sed -n -e "s/\[\(.*\)\]/\1/gp" ${filename})"

}

function count_items_in_segment_grep() {

    # 使用 sed "//,//p" 区间匹配, 然后排除 [client]、空行、注释行, 最后统计
    echo -e "$(sed -n "/\["$1"\]/,/\[.*\]/p" ${filename} | grep -v "\[.*\]" | grep -v "^\#" | grep -v "^$" | wc -l)"
}

function count_items_in_segment_sed() {

    # 使用 sed "//,//p" 区间匹配, 然后排除 [client]、空行、注释行, 最后统计
    echo -e "$(sed -n "/\["$1"\]/,/\[.*\]/p" ${filename} | sed '/\[.*\]/d' | sed '/^\#/d' | sed '/^$/d' | wc -l)"
}

function main() {

    create_my_cnf
    index=0
    for segment in $(get_all_segment); do
        index=$((${index} + 1))
        # echo -e "第 ${index} 个配置项:${segment} 共有 $(count_items_in_segment_sed ${segment}) 个配置项."
        # echo -e "第 ${index} 个配置项:${segment} 共有 $(count_items_in_segment_grep ${segment}) 个配置项."
        printf "${Green_font_prefix}第 %d 个配置项: %12s 共有 %2d 个配置项.(sed)${Font_color_suffix}\n" ${index} ${segment} $(count_items_in_segment_sed ${segment})
        printf "${Blue_font_prefix}第 %d 个配置项: %12s 共有 %2d 个配置项.(grep)${Font_color_suffix}\n" ${index} ${segment} $(count_items_in_segment_grep ${segment})
    done
    echo -e "\n ------ my.cnf 共有 ${index} 个段. ------"

    # 删除文件
    rm -rf ${filename}
}

main
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

# 运行结果

第 1 个配置项:      client 共有  2 个配置项.(sed)
第 1 个配置项:      client 共有  2 个配置项.(grep)
第 2 个配置项:      server 共有 12 个配置项.(sed)
第 2 个配置项:      server 共有 12 个配置项.(grep)
第 3 个配置项:      mysqld 共有 11 个配置项.(sed)
第 3 个配置项:      mysqld 共有 11 个配置项.(grep)
第 4 个配置项: mysqld_safe 共有  7 个配置项.(sed)
第 4 个配置项: mysqld_safe 共有  7 个配置项.(grep)
第 5 个配置项:    embedded 共有  8 个配置项.(sed)
第 5 个配置项:    embedded 共有  8 个配置项.(grep)
第 6 个配置项:  mysqld-5.5 共有  9 个配置项.(sed)
第 6 个配置项:  mysqld-5.5 共有  9 个配置项.(grep)

 ------ my.cnf 共有 6 个段. ------
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 利用 sed 删除文件内容

# 删除命令对照表

命令 含义
1d 删除第 1 行内容
1,10d 删除第 1 行到第 10 行内容
1,1+5d 删除第 1 行到第 6 行内容
/pattern1/d 删除包含 pattern1 的行内容
/patttern1/,/pattern2/d 删除从包含 pattern1 到 包含 pattern2 的行内容
/pattern1/,10d 删除从包含 patttern1 到第 10 行的内容
10,/pattern1/d 删除第 10 行到包含 pattern1 的行内容
1. 删除 /etc/passwd 文件中第 20 行内容

   sed -i '20d' /etc/passwd

2. 删除 /etc/passwd 文件中第 8 - 20 行内容

   sed -i '8, 20d' /etc/passwd

3. 删除 /etc/passwd 文件中第 8, +5 行内容

   sed -i '8, +5d' /etc/passwd

4. 删除 /etc/passwd 文件中包含 zsh 或者 bash 的行

   sed -i -e '/bash/d' -e '/zsh/d' /etc/passwd

5. 删除 /etc/passwd 文件中包含 zsh 或者 bash 的行(使用扩展正则表达式)

   sed -i -r '/bash|zsh/d' /etc/passwd

6. 删除 /etc/passwd 文件中包含 /var/spool/mail 的行

   sed -i '\/var\/spool\/mail' /etc/passwd

7. 删除 /etc/passwd 中以 root 开始的行

   sed -i '/^root/d' /etc/passwd

8. 删除 /etc/passwd 中从 mail 开始的行到 ftp 开始的行

   sed -i '/^mail/,/^ftp/d' /etc/passwd

9. 删除 /etc/passwd 中从第 4 行到以 shutdown 结束的行

   sed -i '4,/shutdown$/d' /etc/passwd

10. 删除 /etc/passwd 中从以 bin 开始的行到第 6 行

    sed -i '/^bin/,6d' /etc/passwd
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

# 练习

# 需求描述

处理 nginx 的配置文件 nginx.conf ,文件内容如下:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }

}
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

编写脚本实现以下功能:

  1. 删除配置文件中的所有注释行和空行。
  2. 在配置文件中所有不以 # 开头的行前添加 * 符号。注意:以 # 开头的行不添加。

# 思路分析

function delete_blank_comment_line # 删除空行和注释行
function add_star_before_line # 行前添加 * 号
1
2
  1. 删除注释行。注释行分两种:
    • 以 # 号开头的行:sed -i '/^\#/d' ${filename}
    • 以 空格开头(一个或多个) + # 号的行:sed -i '/[:blank:]*\#/d' ${filename}
  2. 删除空行。空行:sed -i '/^$/d' ${filename}
  3. 不以 # 开头的行前添加 * 符号:sed -i 's/\(^[^\#]\)/*\1/g' ${filename}
  4. 空行前添加 * 符号:sed -i 's/^$/*&/g' ${filename}

# 脚本编写

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 处理 nginx.conf 文件
# 1. function delete_blank_comment_line 删除空行和注释行
# 2. function add_star_before_line 行前添加 * 号

filepath="$PWD"
filename="${filepath}/nginx.conf"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Blue_font_prefix="\033[34m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function create_nginx_conf() {
    cat >${filename} <<EOF
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                      '\$status \$body_bytes_sent "\$http_referer" '
                      '"\$http_user_agent" "\$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }

}
EOF
}

function delete_blank_comment_line() {
    create_nginx_conf
    echo -e "${Blue_font_prefix} ------ 删除空行和注释行后的 nginx.conf 文件内容 ------ ${Font_color_suffix}\n"
    sed -i '/[:blank:]*\#/d;/^$/d' ${filename}
    cat -n ${filename}
    rm -rf ${filename}
}

function add_star_before_line() {
    create_nginx_conf
    echo -e "\n${Green_font_prefix} ------ 删除空行和注释行后的 nginx.conf 文件内容 ------ ${Font_color_suffix}\n"
    sed -i 's/\(^[^\#]\)/*\1/g' ${filename}
    sed -i 's/^$/*&/g' ${filename}
    cat -n ${filename}
    rm -rf ${filename}
}

delete_blank_comment_line
add_star_before_line
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

# 运行结果

 ------ 删除空行和注释行后的 nginx.conf 文件内容 ------

     1    user nginx;
     2    worker_processes auto;
     3    error_log /var/log/nginx/error.log;
     4    pid /run/nginx.pid;
     5    include /usr/share/nginx/modules/*.conf;
     6    events {
     7        worker_connections 1024;
     8    }
     9    http {
    10        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    11                          '$status $body_bytes_sent "$http_referer" '
    12                          '"$http_user_agent" "$http_x_forwarded_for"';
    13        access_log  /var/log/nginx/access.log  main;
    14        sendfile            on;
    15        tcp_nopush          on;
    16        tcp_nodelay         on;
    17        keepalive_timeout   65;
    18        types_hash_max_size 2048;
    19        include             /etc/nginx/mime.types;
    20        default_type        application/octet-stream;
    21        include /etc/nginx/conf.d/*.conf;
    22        server {
    23            listen       80 default_server;
    24            listen       [::]:80 default_server;
    25            server_name  _;
    26            root         /usr/share/nginx/html;
    27            include /etc/nginx/default.d/*.conf;
    28            location / {
    29            }
    30            error_page 404 /404.html;
    31            location = /404.html {
    32            }
    33            error_page 500 502 503 504 /50x.html;
    34            location = /50x.html {
    35            }
    36        }
    37    }

 ------ 删除空行和注释行后的 nginx.conf 文件内容 ------

     1    # For more information on configuration, see:
     2    #   * Official English Documentation: http://nginx.org/en/docs/
     3    #   * Official Russian Documentation: http://nginx.org/ru/docs/
     4    *
     5    *user nginx;
     6    *worker_processes auto;
     7    *error_log /var/log/nginx/error.log;
     8    *pid /run/nginx.pid;
     9    *
    10    # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
    11    *include /usr/share/nginx/modules/*.conf;
    12    *
    13    *events {
    14    *    worker_connections 1024;
    15    *}
    16    *
    17    *http {
    18    *    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    19    *                      '$status $body_bytes_sent "$http_referer" '
    20    *                      '"$http_user_agent" "$http_x_forwarded_for"';
    21    *
    22    *    access_log  /var/log/nginx/access.log  main;
    23    *
    24    *    sendfile            on;
    25    *    tcp_nopush          on;
    26    *    tcp_nodelay         on;
    27    *    keepalive_timeout   65;
    28    *    types_hash_max_size 2048;
    29    *
    30    *    include             /etc/nginx/mime.types;
    31    *    default_type        application/octet-stream;
    32    *
    33    *    # Load modular configuration files from the /etc/nginx/conf.d directory.
    34    *    # See http://nginx.org/en/docs/ngx_core_module.html#include
    35    *    # for more information.
    36    *    include /etc/nginx/conf.d/*.conf;
    37    *
    38    *    server {
    39    *        listen       80 default_server;
    40    *        listen       [::]:80 default_server;
    41    *        server_name  _;
    42    *        root         /usr/share/nginx/html;
    43    *
    44    *        # Load configuration files for the default server block.
    45    *        include /etc/nginx/default.d/*.conf;
    46    *
    47    *        location / {
    48    *        }
    49    *
    50    *        error_page 404 /404.html;
    51    *        location = /404.html {
    52    *        }
    53    *
    54    *        error_page 500 502 503 504 /50x.html;
    55    *        location = /50x.html {
    56    *        }
    57    *    }
    58    *
    59    # Settings for a TLS enabled server.
    60    #
    61    #    server {
    62    #        listen       443 ssl http2 default_server;
    63    #        listen       [::]:443 ssl http2 default_server;
    64    #        server_name  _;
    65    #        root         /usr/share/nginx/html;
    66    #
    67    #        ssl_certificate "/etc/pki/nginx/server.crt";
    68    #        ssl_certificate_key "/etc/pki/nginx/private/server.key";
    69    #        ssl_session_cache shared:SSL:1m;
    70    #        ssl_session_timeout  10m;
    71    #        ssl_ciphers HIGH:!aNULL:!MD5;
    72    #        ssl_prefer_server_ciphers on;
    73    #
    74    #        # Load configuration files for the default server block.
    75    #        include /etc/nginx/default.d/*.conf;
    76    #
    77    #        location / {
    78    #        }
    79    #
    80    #        error_page 404 /404.html;
    81    #        location = /404.html {
    82    #        }
    83    #
    84    #        error_page 500 502 503 504 /50x.html;
    85    #        location = /50x.html {
    86    #        }
    87    #    }
    88    *
    89    *}
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

# 利用 sed 修改文件内容

# 修改命令对照表

命令 含义
1s/old/new 替换第 1 行内容中第一个 old 替换为 new
1,10s/old/new 替换第 1 行到第 10 行内容中第一个 old 替换为 new
1,1+5s/old/new 替换第 1 行到第 6 行内容中第一个 old 替换为 new
/pattern1/s/old/new 替换包含 pattern1 的行内容中第一个 old 替换为 new
/patttern1/,/pattern2/s/old/new 替换从包含 pattern1 到 包含 pattern2 的行内容中第一个 old 替换为 new
/pattern1/,10s/old/new 替换从包含 patttern1 到第 10 行的内容中第一个 old 替换为 new
10,/pattern1/s/old/new 替换第 10 行到包含 pattern1 的行内容中第一个 old 替换为 new
1. 替换 passwd 文件中第 1 行内容中第一个 root 替换为 ROOT

   sed -i '1s/root/ROOT' passwd

2. 替换 passwd 文件中第 5 - 10 行内容中所有的 /sbin/nologin 替换为 /bin/bash

   sed -i '5, 20s/\/sbin\/nologin/\/bin\/bash/g' passwd

3. 替换 passwd 文件中第 5, +5 行( 5 - 11 )内容中所有的 games 替换为 movies(games 在 11 行)

   sed -i '5, +5s/games/movies/g' passwd

4. 替换 passwd 文件中包含 zsh 或者 bash 的行内容中所有的 zsh|bash 替换为 powershell

   sed -i -e '/bash/s/bash/powershell/g' -e '/zsh/s/zsh/powershell/g' passwd

5. 替换 passwd 文件中包含 zsh 或者 bash 的行内容中所有的 bin 替换为 BIN(使用扩展正则表达式)

   sed -i -r '/bash|zsh/s/bin/bin/g' passwd

6. 替换 passwd 文件中包含 /var/spool/mail 的行内容中第一个 /sbin/nologin 替换为 /bin/zsh

   sed -i '\/var\/spool\/mail/s/\/sbin\/nologin/\/bin\/zsh' passwd

7. 替换 passwd 中以 root 开始的行内容中所有的 root 替换为 jaime

   sed -i '/^root/s/root/jaime/g' passwd

8. 替换 passwd 中从 mail 开始的行到 ftp 开始的行中所有的 /sbin/nologin 替换为 /bin/bash

   sed -i '/^mail/,/^ftp/s/\/sbin\/nologin/\/bin\/bash/g' passwd

9. 替换 passwd 中从第 4 行到以 shutdown 结束的行中所有的 nologin 替换为 zsh

   sed -i '4,/shutdown$/s/nologin/zsh/g' passwd

10. 替换 passwd 中从以 bin 开始的行到第 6 行中第 2 个开始所有的 bin 替换为 BIN

    sed -i '/^bin/,6s/bin/BIN/2g' passwd
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

# 练习

# 需求描述

处理密码文件 password ,文件内容如下:

LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
luff-famed-assault-zooid-heighten-mummer-epitome-coke
lawmaker-rerun-ratchet-grotto-floodlit-glitter-mock-nebulous
vermin-opine-bunk-piquant-crabby-masterly-halcyon-oatmeal
Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
Will-olin-acrylic-try-stasis-salivate-hummock-convolve
1
2
3
4
5
6
7
8
9
10
11
12

编写脚本实现以下功能:

  1. 删除文件中的数字。
  2. 小写字母转大写。
  3. 大写字母转小写。
  4. 字母大小写反转。

# 思路分析

1. function delete_number # 删除文件中的数字
2. function to_uppercase # 小写字母转大写
3. function to_lowercase # 大写字母转小写
4. function reverse_string_case # 字母大小写反转
1
2
3
4

# 脚本编写

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 处理 password 文件
# 1. function delete_number # 删除文件中的数字
# 2. function to_uppercase 小写字母转大写
# 3. function to_lowercase 大写字母转小写
# 4. function reverse_string_case 字母大小写反转

filepath="$PWD"
filename="${filepath}/password"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Blue_font_prefix="\033[34m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"

function create_password() {
    cat >${filename} <<EOF
LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
luff-famed-assault-zooid-heighten-mummer-epitome-coke
lawmaker-rerun-ratchet-grotto-floodlit-glitter-mock-nebulous
vermin-opine-bunk-piquant-crabby-masterly-halcyon-oatmeal
Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
Will-olin-acrylic-try-stasis-salivate-hummock-convolve
EOF
}
function delete_number() {
    create_password && cp ${filename} ${filename}.bak
    echo -e "${Green_font_prefix} ------ 删除数字后的 password 文件内容 ------ ${Font_color_suffix}\n" && sed -i 's/[0-9]*//g' ${filename}
    diff ${filename}.bak ${filename}
    rm -rf ${filename}.bak ${filename}
}

function to_uppercase() {
    create_password && cp ${filename} ${filename}.bak
    echo -e "\n${Green_font_prefix} ------ 小写字母转大写后的 password 文件内容 ------ ${Font_color_suffix}\n" && sed -i 's/[a-z]/\u&/g' ${filename}
    diff ${filename}.bak ${filename}
    rm -rf ${filename}.bak ${filename}

    create_password && cp ${filename} ${filename}.bak
    echo -e "\n${Green_font_prefix} ------ 第一个小写字母转大写后的 password 文件内容 ------ ${Font_color_suffix}\n" && sed -i 's/\b[a-z]/\u&/g' ${filename}
    diff ${filename}.bak ${filename}
    rm -rf ${filename}.bak ${filename}
}

function to_lowercase() {
    create_password && cp ${filename} ${filename}.bak
    echo -e "\n${Green_font_prefix} ------ 大写字母转小写后的 password 文件内容 ------ ${Font_color_suffix}\n" && sed -i 's/[A-Z]/\l&/g' ${filename}
    diff ${filename}.bak ${filename}
    rm -rf ${filename}.bak ${filename}

    create_password && cp ${filename} ${filename}.bak
    echo -e "\n${Green_font_prefix} ------ 第一个大写字母转小写后的 password 文件内容 ------ ${Font_color_suffix}\n" && sed -i 's/\b[A-Z]/\l&/g' ${filename}
    diff ${filename}.bak ${filename}
    rm -rf ${filename}.bak ${filename}
}

function reverse_string_case() {
    create_password
    echo -e "\n${Green_font_prefix} ------ 大小写互转后的 password 文件内容 ------ ${Font_color_suffix}\n"
    cat ${filename} | tr '[a-zA-Z]' '[A-Za-z]' >${filename}.bak
    diff ${filename}.bak ${filename}
    rm -rf ${filename}.bak ${filename}
}

delete_number
to_uppercase
to_lowercase
reverse_string_case
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

# 运行结果

 ------ 删除数字后的 password 文件内容 ------

1,6c1,6
< LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
< G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
< ,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
< 37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
< L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
< JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
---
> LUD?N\>*bjQ.Kg*=ZrbbY#GJvQv?NZJ-psgC?QHwY,F%u~Uc:]}p:j!XmjPo=
> G.t*pk_pbAAWBmJpZMZXoGRaeMZab.nVrtAEM~a?_my@CWg!eEpwMdiTz
> ,Pyv?]jEU,NPAaX\>cR#x,wgxX\>HCD\>@TXFNkzawsNud~PpuZiPemGh}rxbx
> dmJBswvFxwo}mNFmqtmZ:BmLzLdQE+QH},YEZwuVET.iZtLmu,bHz
> Li+k\)vQHfF:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^?mXPssYGMT@E_XwBCG-B
> JB\>=H!usea!fwPZQWnt,,HtGJo=cV%t*!N-mQep\>]A*TMJ\>%FU_%^W!

 ------ 小写字母转大写后的 password 文件内容 ------

1,12c1,12
< LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
< G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
< ,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
< 37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
< L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
< JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
< luff-famed-assault-zooid-heighten-mummer-epitome-coke
< lawmaker-rerun-ratchet-grotto-floodlit-glitter-mock-nebulous
< vermin-opine-bunk-piquant-crabby-masterly-halcyon-oatmeal
< Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
< Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
< Will-olin-acrylic-try-stasis-salivate-hummock-convolve
---
> LUD?N52\>*BJQ.KG*=ZRBBY#GJVQV?N1ZJ-PSGC?QHW77Y2,F%U~UC:]}P:J!XMJPO=
> G.T*PK_PBAAWBM2JPZMZXOGR2AEMZAB6.NVR9TAE04M~A?8_MY@CWG!EEP5WM1DITZ
> ,PYV?]JEU,NPAA7X\>1CR#X5,WGXX\>HCD3\>@TX6FNKZA5WS7NUD~PPUZIPEMGH}RXBX
> 37DMJBS3WVFXWO}M76NFM91QTM1Z:BML6ZLDQE+QH},Y531EZWUVET.IZTLMU,BH0Z
> L8I+K\)7VQHFF6:,TZDZH\)A_ETZ.NJ-\>NXTU.CC,:OW^9?MXPSSYGM99T@E_XWBCG-B
> JB\>=H!US6E12A!6FWPZQWNT,,HT8GJO=CV%T5*!N-48MQEP\>]0A*7TMJ\>%FU_%^W4!
> LUFF-FAMED-ASSAULT-ZOOID-HEIGHTEN-MUMMER-EPITOME-COKE
> LAWMAKER-RERUN-RATCHET-GROTTO-FLOODLIT-GLITTER-MOCK-NEBULOUS
> VERMIN-OPINE-BUNK-PIQUANT-CRABBY-MASTERLY-HALCYON-OATMEAL
> BUYOUT-MOLY-NITROGEN-KNOWHOW-FROTH-UNTIL-SAUNTER-HURD
> BREADTH-ORLANDO-URUGUAY-LAMPOON-CANE-ALBUMEN-ANTENNAE-JAPAN
> WILL-OLIN-ACRYLIC-TRY-STASIS-SALIVATE-HUMMOCK-CONVOLVE

 ------ 第一个小写字母转大写后的 password 文件内容 ------

1,12c1,12
< LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
< G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
< ,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
< 37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
< L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
< JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
< luff-famed-assault-zooid-heighten-mummer-epitome-coke
< lawmaker-rerun-ratchet-grotto-floodlit-glitter-mock-nebulous
< vermin-opine-bunk-piquant-crabby-masterly-halcyon-oatmeal
< Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
< Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
< Will-olin-acrylic-try-stasis-salivate-hummock-convolve
---
> LUD?N52\>*BjQ.Kg*=ZrbbY#GJvQv?N1ZJ-PsgC?QHw77Y2,F%U~Uc:]}P:J!XmjPo=
> G.T*Pk_pbAAWBm2JpZMZXoGR2aeMZab6.NVr9tAE04M~A?8_my@CWg!EEp5wM1diTz
> ,Pyv?]JEU,NPAa7X\>1cR#X5,WgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}Rxbx
> 37dmJBs3wvFxwo}M76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.IZtLmu,BH0z
> L8i+K\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>NXtU.CC,:Ow^9?MXPssYGM99T@E_XwBCG-B
> JB\>=H!Us6e12a!6fwPZQWnt,,Ht8GJo=CV%T5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
> Luff-Famed-Assault-Zooid-Heighten-Mummer-Epitome-Coke
> Lawmaker-Rerun-Ratchet-Grotto-Floodlit-Glitter-Mock-Nebulous
> Vermin-Opine-Bunk-Piquant-Crabby-Masterly-Halcyon-Oatmeal
> Buyout-Moly-Nitrogen-Knowhow-Froth-Until-Saunter-Hurd
> Breadth-Orlando-Uruguay-Lampoon-Cane-Albumen-Antennae-Japan
> Will-Olin-Acrylic-Try-Stasis-Salivate-Hummock-Convolve

 ------ 大写字母转小写后的 password 文件内容 ------

1,6c1,6
< LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
< G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
< ,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
< 37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
< L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
< JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
---
> lud?n52\>*bjq.kg*=zrbby#gjvqv?n1zj-psgc?qhw77y2,f%u~uc:]}p:j!xmjpo=
> g.t*pk_pbaawbm2jpzmzxogr2aemzab6.nvr9tae04m~a?8_my@cwg!eep5wm1ditz
> ,pyv?]jeu,npaa7x\>1cr#x5,wgxx\>hcd3\>@tx6fnkza5ws7nud~ppuzipemgh}rxbx
> 37dmjbs3wvfxwo}m76nfm91qtm1z:bml6zldqe+qh},y531ezwuvet.iztlmu,bh0z
> l8i+k\)7vqhff6:,tzdzh\)a_etz.nj-\>nxtu.cc,:ow^9?mxpssygm99t@e_xwbcg-b
> jb\>=h!us6e12a!6fwpzqwnt,,ht8gjo=cv%t5*!n-48mqep\>]0a*7tmj\>%fu_%^w4!
10,12c10,12
< Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
< Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
< Will-olin-acrylic-try-stasis-salivate-hummock-convolve
---
> buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
> breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
> will-olin-acrylic-try-stasis-salivate-hummock-convolve

 ------ 第一个大写字母转小写后的 password 文件内容 ------

1,6c1,6
< LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
< G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
< ,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
< 37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
< L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
< JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
---
> lUD?n52\>*bjQ.kg*=zrbbY#gJvQv?n1ZJ-psgC?qHw77Y2,f%u~uc:]}p:j!xmjPo=
> g.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@cWg!eEp5wM1diTz
> ,pyv?]jEU,nPAa7X\>1cR#x5,wgxX\>hCD3\>@tX6FNkza5ws7Nud~ppuZiPemGh}rxbx
> 37dmJBs3wvFxwo}m76NFm91qtm1Z:bmL6zLdQE+qH},y531EZwuVET.iZtLmu,bH0z
> l8i+k\)7vQHfF6:,tZdZh\)a_eTz.nJ-\>nXtU.cC,:ow^9?mXPssYGM99T@e_XwBCG-b
> jB\>=h!us6e12a!6fwPZQWnt,,ht8GJo=cV%t5*!n-48mQep\>]0A*7TMJ\>%fU_%^w4!
10,12c10,12
< Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
< Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
< Will-olin-acrylic-try-stasis-salivate-hummock-convolve
---
> buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
> breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
> will-olin-acrylic-try-stasis-salivate-hummock-convolve

 ------ 大小写互转后的 password 文件内容 ------

1,12c1,12
< lud?n52\>*BJq.kG*=zRBBy#gjVqV?n1zj-PSGc?qhW77y2,f%U~uC:]}P:J!xMJpO=
< g.T*PK_PBaawbM2jPzmzxOgr2AEmzAB6.NvR9Tae04m~A?8_MY@cwG!EeP5Wm1DItZ
< ,pYV?]Jeu,npaA7x\>1Cr#X5,WGXx\>hcd3\>@tx6fnKZA5WS7nUD~pPUzIpEMgH}RXBX
< 37DMjbS3WVfXWO}M76nfM91QTM1z:bMl6ZlDqe+qh},y531ezWUvet.IzTlMU,Bh0Z
< l8I+K\)7VqhFf6:,tzDzH\)a_EtZ.nj-\>NxTu.Cc,:OW^9?MxpSSygm99t@e_xWbcg-b
< jb\>=h!US6E12A!6FWpzqwNT,,hT8gjO=Cv%T5*!n-48MqEP\>]0a*7tmj\>%fu_%^w4!
< LUFF-FAMED-ASSAULT-ZOOID-HEIGHTEN-MUMMER-EPITOME-COKE
< LAWMAKER-RERUN-RATCHET-GROTTO-FLOODLIT-GLITTER-MOCK-NEBULOUS
< VERMIN-OPINE-BUNK-PIQUANT-CRABBY-MASTERLY-HALCYON-OATMEAL
< bUYOUT-MOLY-NITROGEN-KNOWHOW-FROTH-UNTIL-SAUNTER-HURD
< bREADTH-ORLANDO-URUGUAY-LAMPOON-CANE-ALBUMEN-ANTENNAE-JAPAN
< wILL-OLIN-ACRYLIC-TRY-STASIS-SALIVATE-HUMMOCK-CONVOLVE
---
> LUD?N52\>*bjQ.Kg*=ZrbbY#GJvQv?N1ZJ-psgC?QHw77Y2,F%u~Uc:]}p:j!XmjPo=
> G.t*pk_pbAAWBm2JpZMZXoGR2aeMZab6.nVr9tAE04M~a?8_my@CWg!eEp5wM1diTz
> ,Pyv?]jEU,NPAa7X\>1cR#x5,wgxX\>HCD3\>@TX6FNkza5ws7Nud~PpuZiPemGh}rxbx
> 37dmJBs3wvFxwo}m76NFm91qtm1Z:BmL6zLdQE+QH},Y531EZwuVET.iZtLmu,bH0z
> L8i+k\)7vQHfF6:,TZdZh\)A_eTz.NJ-\>nXtU.cC,:ow^9?mXPssYGM99T@E_XwBCG-B
> JB\>=H!us6e12a!6fwPZQWnt,,Ht8GJo=cV%t5*!N-48mQep\>]0A*7TMJ\>%FU_%^W4!
> luff-famed-assault-zooid-heighten-mummer-epitome-coke
> lawmaker-rerun-ratchet-grotto-floodlit-glitter-mock-nebulous
> vermin-opine-bunk-piquant-crabby-masterly-halcyon-oatmeal
> Buyout-moly-nitrogen-knowhow-froth-until-saunter-hurd
> Breadth-orlando-uruguay-lampoon-cane-albumen-antennae-japan
> Will-olin-acrylic-try-stasis-salivate-hummock-convolve
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

# 利用 sed 追加文件内容

# 追加命令对照表

命令 含义
a 匹配行后追加
i 匹配行前增加
r 外部文件读入,匹配行后追加
w 匹配行写入外部文件

# 示例详解

1. a 匹配行前追加 append

    - passwd 文件第 10 行后面追加 "Add Line Behind."
        sed -i "10a Add Line Behind." passwd
    - passwd 文件第 10 - 20 行后追加 "Test Line Behind."
        sed -i "10, 20a Test line Behind." passwd
    - passwd 文件包含 /bin/bash 的行后面追加 "Insert Line For /bin/bash Behind."
        sed -i "/\/bin\/bash/a Insert Line For /bin/bash Behind." passwd

2. i 匹配行前插入 insert

    - passwd 文件中以 yarn 开头的行前插入 "Add Line Before."
        sed -i "/^yarn/i Add Line Before."
    - passwd 文件每一行前面插入 "Insert Line Before Every Line."
        sed -i "i Insert Line Before Every Line."

3. r 外部文件读入,匹配行后追加

    - 将 /etc/fstab 文件中的内容追加到 passwd 文件中第 20 行后面
        sed -i "20r /etc/fstab" passwd
    - 将 /etc/inittab 文件内容追加到 passwd 文件中包含 /sbin/nologin 的行后
        sed -i "/\/sbin\/nologin/r /etc/inittab" passwd
    - 将 /etc/vconsole.conf 文件内容追加到 passwd 文件中以 ftp 开头的行到第 18 行
        sed -i "/^ftp/,18r /etc/vconsole.conf" passwd

4. w 匹配行写入外部文件

    - 将 passwd 文件中包含 /bin/bash 的行追加到 /tmp/sed.txt 文件中
        sed -i "/\/bin\/bash/w /tmp/sed.txt" passwd
    - 将 passwd 文件中第 10 行开始到以 hdfs 开头的行区间内的所有内容全部追加到 /tmp/sed-1.txt 文件中
        sed -i "10,/^hdfs/w /tmp/sed-1.txt" passwd
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

本文代码:06-shell (opens new window)

文本处理命令 grep

← 文本处理命令 grep

Theme by Vdoing | Copyright © 2020-2022 JaimeZeng | ❤️ | CC BY-NC-SA 4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式