标签(空格分隔): Linux 实战教学笔记 - 陈思齐
---
- [root@chensiqi1 ~]# cat /etc/redhat-release
- CentOS release 6.8 (Final)
- [root@chensiqi1 ~]# uname -r
- 2.6.32-642.el6.x86_64
- [root@chensiqi1 ~]# sed --version # 查看sed软件版本
- GNU sed version 4.2.1
- sed [options] [sed -commands][input -file]
- sed [选项] 【sed命令】 【输入文件】
概括流程:
小知识:
详细流程:
文件 person.txt 在模式空间的完整处理流程
上面的流程概括如下图所示:
Sed 软件有两个内置的存储空间:
option[选项] | 解释说明(带 * 的为重点) |
---|---|
-n | 取消默认的 sed 软件的输出,常与 sed 命令的 p 连用。* |
-e | 一行命令语句可以执行多条 sed 命令 |
-f | 选项后面可以接 sed 脚本的文件名 |
-r | 使用扩展正则表达式,默认情况 sed 只识别基本正则表达式 * |
-i | 直接修改文件内容,而不是输出到终端,如果不使用 - i 选项 sed 软件只是修改在内存中的数据,并不会影响磁盘上的文件 * |
特殊符号 | 解释说明(带 * 的为重点) |
---|---|
! |
|
= | 打印当前行行号 |
~ | "First~step" 表示从 First 行开始,以步长 Step 递增 |
& | 代表被替换的内容 |
: |
|
{} | 对单个地址或地址范围执行批量操作 |
+ | 地址范围中用到的符号,做加法运算 |
- [root@chensiqi1~]#cat > person.txt << KOF > 101,
- chensiqi,
- CEO > 102,
- zhangyang,
- CTO > 103,
- Alex,
- COO > 104,
- yy,
- CFO > 105,
- feixue,
- CIO > KOF#KOF必须成对出现,表示终止输入命令说明:使用一条cat命令创建多行文本,文件包含上面的内容,后面的操作都会使用这个文件。
- [root@chensiqi1~]#sed '2a 106,dandan,CSO'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 106,
- dandan,
- CSO#这就是新增那句103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO
命令行详解:
最后接上你想要处理的文件 person.txt
Sed 为何用单引号?
- [root@chensiqi1~]#cat person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO[root@chensiqi1~]#sed '2i $PATH'person.txt#单引号--文本内容原封不动插入101,
- chensiqi,
- CEO $PATH 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO[root@chensiqi1~]#sed 2i $PATH person.txt#不加引号,linux无法辨认空格,不会把有空格的命令当成一条命令来执行sed: -e expression#1,
- char 2 : expected\after`a ', `c'or`i '
- [root@chensiqi1 ~]# sed "2i $PATH" person.txt #双引号--变量$PATH被解析以后在当作文本进行插入
- 101,chensiqi,CEO
- /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
- 102,zhangyang,CTO
- 103,Alex,COO
- 104,yy,CFO
- 105,feixue,CIO'
结论一:
结论二:
示例准备,请执行如下完整命令生成 test.txt 文件内容:
- [root@chensiqi1 ~]# cat > test.txt <<EOF
- > welcome to my blog.http://www.cnblogs.com/chensiqiqi/
- >
- > if you like my blog\'s contents,pls support me.
- >
- >
- >
- > bye!boys and girls.
- > EOF
- 命令说明:以上就是cat的生产环境常用的生成或为文件追加内容的方法,请不要忽略上文中的空行。另外,如果内容中有单引号,$符号等特殊符号作为内容时要用"\"转义。
以上命令执行过程及结果:
- [root@chensiqi1 ~]# echo "chensiqi";echo "chensiqi"
- chensiqi
- chensiqi
- 命令说明:上面的命令用分号";"连接了两条命令,然后输出结果为2行chensiqi,但是有没有更简单的方法呢?
- [root@chensiqi1 ~]# echo -e "chensiqi\nchensiqi"
- chensiqi
- chensiqi
- 命令说明:这里就"\n"派上用场了,行与行之间是以"\n"作为分隔符的,所以"chensiqi\nchensiqi"就等效于2行chensiqi。接下来我们用echo命令实验一下,其中-e参数表示字符串中如果出现以下特殊字符(\n代表换行,\t代表Tab键等),则加以特殊处理,而不会将它当成一般文字输出。如果大家想详细了解echo命令的详细用法,请持续关注我的博客。
学习完换行符,我们来看一下 sed 命令如何使用
!
- [root@chensiqi1~]#sed '2a 106,dandan,CSO\n107,bingbing,CCO'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 106,
- dandan,
- CSO#同时追加多行107,
- bingbing,
- CCO#同时追加多行103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO EOF
命令行分析:
最后接上你想要处理的文件 person.txt
- [root@chensiqi1 ~]# echo chensiqi
- chensiqi
- [root@chensiqi1 ~]# echo \
- > chensiqi
- chensiqi
- [root@chensiqi1 ~]# echo \
- > chensiqi \
- > is \
- > me
- chensiqi is me
- 命令说明:一条命令可以通过\符号进行多行输出
- [root@chensiqi1~]#sed '2a 106,dandan,CSO \
- > 107,bingibng,CCO'\ > person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 106,
- dandan,
- CSO 107,
- bingibng,
- CCO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO EOF命令说明:结果和第一种方法是一样的,但是我们也发现这种方法比较麻烦,因此建议大家使用第一种方法。
企业案例 1: 优化 SSH 配置(一键完成增加若干参数)
- Port 52113
- PermitRootLogin no
- PermitEmptyPasswords no
- UseDNS no
- GSSAPIAuthentication no
这道企业面试题可以用我们学过的 sed 命令多行追加功能就可以搞定。
- [root@chensiqi1 ~]# sed -i '13i Port 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\nGSSAPIAuthentication no' /etc/ssh/sshd_config
- 命令说明:题目要求在第13行前插入,那就需要使用命令13i。有同学做个题目时,是这样想的,在13行前,那不就是12行后吗,12a也是可以的。是的,这样也是没错的,这可以算是第二种方法。
- 最后插入的5行内容使用"\n"就可以变成一行了。
- 上面还有一个没讲过的选项"-i",这个选项能够实际的修改文件内容,大家练习时可以去掉,防止改掉了配置文件。如果使用了-i,可以用备份文件还原。当然,在生产环境修改配置文件那就需要用-i选项了。
- [root@chensiqi1 ~]# sed -n '13,17p' /etc/ssh/sshd_config
- Port 52113
- PermitRootLogin no
- PermitEmptyPasswords no
- UseDNS no
- GSSAPIAuthentication no
- 命令说明:查看增加的文本内容,选项-n与命令p的具体用法见后文的6.2.4查。
地址范围 | 含义 |
---|---|
10{sed-commands} | 对第 10 行操作 |
10,20{sed-commands} | 对 10 到 20 行操作,包括第 10,20 行 |
10,+20{sed-commands} | 对 10 到 30(10+20)行操作,包括第 10,30 行 |
1~2{sed-commands} | 对 1,3,5,7..... 行操作 |
10,\${sed-commands} | 对 10 到最后一行($ 代表最后一行)操作,包括第 10 行 |
/chensiqi/{sed-commands} | 对匹配 chensiqi 的行操作 |
/chensiqi/,/Alex/{sed-commands} | 对匹配 chensiqi 的行到匹配 Alex 的行操作 |
/chensiqi/,\${sed-commands} | 对匹配 chensiqi 的行到最后一行操作 |
/chensiqi/,10{sed-commands} | 对匹配 chensiqi 的行到第 10 行操作,
|
1,/Alex/{sed-commands} | 对第 1 行到匹配 Alex 的行操作 |
/chensiqi/,+2{sed-commands} | 对匹配 chensiqi 的行到其后的 2 行操作 |
下面用具体的例子演示一下,测试文件还是 person.txt
- [root@chensiqi1 ~]# sed 'd' person.txt
- [root@chensiqi1 ~]#
- 命令说明:如果在sed命令前面不指定地址范围,那么默认会匹配所有行,然后使用d命令删除功能就会删除这个文件的所有内容
- [root@chensiqi1~]#sed '2d'person.txt 101,
- chensiqi,
- CEO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:这个单行删除想必大家能理解,指定删除第2行的文本102,zhangyang,CTO
- [root@chensiqi1 ~]# sed '2,5d' person.txt
- 101,chensiqi,CEO
- 命令说明:'2,5d'指定删除第2行到第5行的内容,d代表删除操作。
- [root@chensiqi1~]#sed '/zhangyang/d'person.txt 101,
- chensiqi,
- CEO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:在sed软件中,使用正则的格式和awk一样,使用2个" / "包含指定的正则表达式,即" / 正则表达式 / "。
当然也可以使用两个正则表达式,如下例所示。
- [root@chensiqi1~]#sed '/chensiqi/,/Alex/d'person.txt 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:这是正则表达式形式的多行删除,也是以逗号分隔2个地址,最后结果是删除包含"chensiqi"的行到包含"Alex"的行
- [root@chensiqi1~]#sed '3,$d'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO命令说明:学过正则表达式后我们知道"$"代表行尾,但是在sed中就有一些变化了,"$"在sed中代表文件的最后一行。因此本例子的含义是删除第3行到最后一行的文本,包含第3行和最后一行,因此剩下第1,2行的内容。
接下来我们看一些特殊情况。
- [root@chensiqi1~]#sed '/chensiqi/,3d'person.txt 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:这个例子是删除包含"chensiqi"的行到第3行的内容。但这种组合有一个比较特殊的情况,如果前3行之外还有这个"chensiqi"字眼,sed软件还是会找他"麻烦",请看下面例子。 [root@chensiqi1~]#sed '$a 106,chensiqi,CMO'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO 106,
- chensiqi,
- CMO命令说明:为了不造成同学们实验文本改来改去导致不同意,因此我用上面的命令语句只是临时修改内存数据,然后通过管道符号传给sed软件。 [root@chensiqi1~]#sed '$a 106,chensiqi,CMO'person.txt | sed '/chensiqi/,3d'104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:从命令结果我们可以看到,不仅是第1行(101,chensiqi,CEO)到第3行(103,ALex,COO)被删除了,而且最后一行(106,chensiqi,CMO)也被删除了。因此我们可以得出一个小结论,sed软件使用正则表达式会找出所有匹配的行,即使是有数字地址限制。
再来看一个特殊情况。
- [root@chensiqi1 ~]# sed '2,/O/d' person.txt
- 101,chensiqi,CEO
- 104,yy,CFO
- 105,feixue,CIO
- 命令说明:
- 从第2行开始删除到含字母O的行结束,但是我们发现第3,4,5行都含有字母O,命令结果显示只删除了第2,3行,属于最短删除。这个怎么理解?
- 还是可以从上面命令执行流程图理解,从第2行开始循环,sed软件第一次遇到字母O(第三行)就认为循环结束了。
- [root@chensiqi1 ~]# sed '2,/o/d' person.txt
- 101,chensiqi,CEO
- 命令说明:
- 从第2行开始删除,但是后面文本没有字母O,因此一直循环下去,直到文本结束,sed软件自动终止。
例子:
- [root@chensiqi1 ~]# seq 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 命令说明:seq命令能够生成从1到10的数字序列。
- [root@chensiqi1 ~]# seq 10 | sed -n '1~2p'
- 1
- 3
- 5
- 7
- 9
- 命令说明:
- 上面的命令主要验证特殊符号"~"的效果,其他sed命令用法n和p请见后文详解,大家只需要知道这个命令可以将"1~2"指定的行显示出来即可。
- 上面例子测试了"1~2"的效果,大家也可以手动测试一下"2~2","1~3","2~3",看一下他们的结果是不是符合等差数列。
补充小知识:
- [root@chensiqi1 ~]# seq 1 2 10
- 1
- 3
- 5
- 7
- 9
- 命令说明:seq命令格式seq起始值 公差 结束值
再来一例:
- [root@chensiqi1~]#sed '1~2d'person.txt 102,
- zhangyang,
- CTO 104,
- yy,
- CFO命令说明:"1~2"这是指定行数的另一种格式,从第1行开始以步长2递增的行(1,3,5),因此删掉第1,3,5行,即所有的奇数行。
- [root@chensiqi1~]#sed '1,+2d'person.txt 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:这其实是做个加法运算,'1, + 2d' == >删除第1行到第3(1 + 2)行的文本。
上面是特殊符号 "+" 的用法,大家知道即可。
- [root@chensiqi1~]#sed '2,3!d'person.txt 102,
- zhangyang,
- CTO 103,
- Alex,
- COO命令说明:在地址范围"2,3"后面加上"!",如果不加"!"表示删除第2行和第3行,结果如下面的例子所示,然后加上"!"的结果就是除了第2行和第3行以外的内容都删除,这个方法可以作为显示文件的第2,3行题目的补充方法。 [root@chensiqi1~]#sed '2,3d'person.txt 101,
- chensiqi,
- CEO 104,
- yy,
- CFO 105,
- feixue,
- CIO
企业案例 2: 打印文件内容但不包含 chensiqi
- [root@chensiqi1~]#sed '/chensiqi/d'person.txt 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:删除包含"chensiqi"的行,就直接用正则匹配字符串chensiqi即可
例子:
- [root@chensiqi1~]#sed '2c 106,dandan,CSO'person.txt 101,
- chensiqi,
- CEO 106,
- dandan,
- CSO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:使用sed命令c将原来第2行"102,zhangyang,CTO"替换成"106,dandan,
- CSO",
- 整行替换
sed 软件替换模型
sed -i 's / 目标内容 / 替换内容 / g' chensiqi.log
sed -i 's# 目标内容 #替换内容#g'
观察特点
1,两边是引号,引号里面的两边分别为 s 和 g,中间是三个一样的字符 / 或 #作为定界符。字符#能在替换内容包含字符 / 有助于区别。定界符可以是任意字符如:或 | 等,但当替换内容包含定界符时,需要转义 \:或 \|. 经过长期实践,建议大家使用# 作为定界符。
2,定界符 / 或 #,第一个和第二个之间的就是被替换的内容,第二个和第三个之间的就是替换后的内容。
3,s# 目标内容 #替换内容#g ,"目标内容" 能用正则表达式,但替换内容不能用,必须是具体的。因为替换内容使用正则的话会让 sed 软件无所适从,它不知道你要替换什么内容。
4,默认 sed 软件是对模式空间(内存中的数据)操作,而 - i 选项会更改磁盘上的文件内容。
例子:
- [root@chensiqi1~]#sed 's#zhangyang#dandan#g'person.txt 101,
- chensiqi,
- CEO 102,
- dandan,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:将需要替换的文本"zhangyang"放在第一个和第二个"#"之间,将替换后的文本"dandan"放在第二个核第三个"#"之间。结果为第二行的"zhangyang"替换为"dandan"。
修改文件:
- [root@chensiqi1~]#cat person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:从上面命令的结果我们就知道sed命令默认不会修改文件的内容 [root@chensiqi1~]#sed - i 's#zhangyang#dandan#g'person.txt命令说明:如果想真正的修改文件内容,我们就需要使用选项" - i",这个要和sed命令"i"区分开来。同时我们可以发现命令执行后的结果是没有任何输出的。 [root@chensiqi1~]#cat person.txt 101,
- chensiqi,
- CEO 102,
- dandan,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:当我们再次查看这个文件时,我们就发现这个文件已经被修改成功了。因此大家以后如果使用替换功能时,应该首先不用选项" - i"测试一下,确保操作无误,最后使用" - i"修改文件
还原测试文件:
- [root@chensiqi1 ~]# sed -i 's#dandan#zhangyang#g' person.txt
- 命令说明:还原测试文件,这一步大家不要忘了执行,不然后面就跟不上步骤了
企业案例 3:指定行修改配置文件
- [root@chensiqi1~]#sed '3s#0#9#'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 193,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:前面学习的例子在sed命令"s"前没有指定地址范围,因此默认是对所有行进行操作。而这个案例要求只将第3行的0换成9,这里就用到了我们前面学过的地址范围知识,在sed命令"s"前加上"3"就代表对第3行进行替换
- [root@chensiqi1 ~]# cat >test.txt<<KOF #再新建一个简单的测试文本
- > a
- > b
- > a
- > KOF
- [root@chensiqi1 ~]# cat test.txt
- a
- b
- a
- [root@chensiqi1 ~]# x=a #->设置变量x并 赋值a
- [root@chensiqi1 ~]# y=b #-> 设置变量y并赋值b
- [root@chensiqi1 ~]# echo $x
- a
- [root@chensiqi1 ~]# echo $x $y
- a b
- 命令说明:打印变量x,y验证一下,需要使用$符号引用变量
不使用引号:
- [root@chensiqi1 ~]# sed s#$x#$y#g test.txt
- b
- b
- b
- 命令说明:使用变量进行替换,从执行结果中我们可以发现替换成功了,test.txt文件中所有的a都替换成了b。同时我们可以发现s#$x#$y#g没有使用引号,当然这种写法并不是特别标准。
- [root@chensiqi1 ~]# sed 's#'$x'#'$y'#g' test.txt
- b
- b
- b
- 命令说明:表面看起来单引号是可以用的,但其实这里用了障眼法,在你们眼中分段'$x'和'$y',但其实分段是's#'和'#'和'#g',所以$x和$y并没有被引号扩起来,和上面的例子就一样了。
使用 eval 命令:
- [root@chensiqi1 ~]# eval sed 's#$x#$y#g' test.txt
- b
- b
- b
- 命令说明:这里给大家扩展一个Linux内置命令eval,这个命令能读入变量,并将他们组合成一个新的命令,然后执行。首先eval会解析变量$x和变量$y,最后达到的效果和双引号是一样的。
扩展:最快速的获取 IP 地址的方法
- [root@chensiqi1 ~]# hostname -I
- 192.168.197.133
例:echo "I am chensiqi teacher." 如果想保留这一行的单词 chensiqi,删除剩下部分,使用圆括号标记想保留的部分。
- [root@chensiqi1 ~]# echo "I am chensiqi teacher." | sed 's#^.*am \([a-z]\+\) tea.*$#\1#g'
- chensiqi
- [root@chensiqi1 ~]# echo "I am chensiqi teacher." | sed -r 's#^.*am ([a-z]+) tea.*$#\1#g'
- chensiqi
- [root@chensiqi1 ~]# echo "I am chensiqi teacher." | sed -r 's#I (.*) (.*) teacher.#\1\2#g'
- amchensiqi
- 命令说明:
- sed如果不加-r后缀,那么默认不支持扩展正则表达式,需要\符号进行转义。小括号的作用是将括号里的匹配内容进行分组以便在第2和第3个#号之间进行sed的反向引用,\1代表引用第一组,\2代表引用第二组
再来看个题目:请执行命令取出 linux 中的 eth0 的 IP 地址?
- [root@chensiqi1 ~]# ifconfig eth0 | sed -n '2p'
- inet addr:192.168.197.133 Bcast:192.168.197.255 Mask:255.255.255.0
- [root@chensiqi1 ~]# ifconfig eth0 | sed -n '2p' | sed -r 's#^.*addr:(.*) Bcast:.*$#\1#g'
- 192.168.197.133
- 也可以进行组合
- [root@chensiqi1 ~]# ifconfig eth0 | sed -rn '2s#^.*addr:(.*) Bcast:.*$#\1#gp'
- 192.168.197.133
- 命令说明:
- 这道题是需要把ifconfig eth0执行结果的第2行的IP地址取出来,上面答案的思路是用IP地址来替换第2行的内容。
企业案例 4: 系统开机启动项优化(利用 sed)
- [root@chensiqi1 ~]# chkconfig --list | egrep -v "sshd|crond|rsyslog|sysstat|network" | awk '{print $1}' |sed -r 's#^(.*)#chkconfig \1 off#g' |bash
- 这题也可以应用awk直接一步到位
- [root@chensiqi1 ~]# chkconfig --list | egrep -v "sshd|crond|network|rsyslog|sysstat" | awk '{print "chkconfig",$1,"off"}' | bash
- [root@chensiqi1~]#sed - r 's#(.*),(.*),(.*)#& ----- \1 \2 \3#'person.txt 101,
- chensiqi,
- CEO-----101 chensiqi CEO 102,
- zhangyang,
- CTO-----102 zhangyang CTO 103,
- Alex,
- COO-----103 Alex COO 104,
- yy,
- CFO-----104 yy CFO 105,
- feixue,
- CIO-----105 feixue CIO命令说明:1,这里将分组替换和 & 符号放在一起对比2,命令中的分组替换使用了3个小括号,每个小括号分别代表每一行以逗号作为分隔符的每一列。3,上面命令的 & 符号代表每一行,即模型中's#目标内容#替换内容#g'的目标内容。
企业案例 5: 批量重命名文件
当前目录下有文件如下所示:
- [root@chensiqi1 chen]# find ./ -name "*_finished.jpg"
- ./stu_102999_1_finished.jpg
- ./stu_102999_5_finished.jpg
- ./stu_102999_3_finished.jpg
- ./stu_102999_2_finished.jpg
- ./stu_102999_4_finished.jpg
要求用 sed 命令重命名,效果为
stu_102999_1_finished.jpg==>stu_102999_1.jpg, 即删除文件名的_finished
- [root@chensiqi1 chen]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#\1\2#g'
- ./stu_102999_1.jpg
- ./stu_102999_5.jpg
- ./stu_102999_3.jpg
- ./stu_102999_2.jpg
- [root@chensiqi1 chen]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#& \1\2#g'
- ./stu_102999_1_finished.jpg ./stu_102999_1.jpg
- ./stu_102999_5_finished.jpg ./stu_102999_5.jpg
- ./stu_102999_3_finished.jpg ./stu_102999_3.jpg
- ./stu_102999_2_finished.jpg ./stu_102999_2.jpg
- ./stu_102999_4_finished.jpg ./stu_102999_4.jpg
- [root@chensiqi1 chen]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#mv & \1\2#g'
- mv ./stu_102999_1_finished.jpg ./stu_102999_1.jpg
- mv ./stu_102999_5_finished.jpg ./stu_102999_5.jpg
- mv ./stu_102999_3_finished.jpg ./stu_102999_3.jpg
- mv ./stu_102999_2_finished.jpg ./stu_102999_2.jpg
- mv ./stu_102999_4_finished.jpg ./stu_102999_4.jpg
- [root@chensiqi1 chen]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#mv & \1\2#g' |bash
- [root@chensiqi1 chen]# ls
- stu_102999_1.jpg stu_102999_2.jpg stu_102999_3.jpg stu_102999_4.jpg stu_102999_5.jpg
- 命令说明:
- 1."\1"代表前面"(^.*)"匹配内容,"&"代表"s# #"里被替换的内容,这里匹配到的是完整的文件名。
- 2.使用bash命令执行,bash命令执行标准输入的语句,如同我们在命令行输入语句后敲回车。
- [root@chensiqi1~]#sed '2p'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO[root@chensiqi1~]#sed - n '2p'person.txt 102,
- zhangyang,
- CTO命令说明:选项 - n取消默认输出,只输出匹配的文本,大家只需要记住使用命令p必用选项 - n。 [root@chensiqi1~]#sed - n '2,3p'person.txt 102,
- zhangyang,
- CTO 103,
- Alex,
- COO命令说明:查看文件的第2行到3行,使用地址范围"2,3"。取行就用sed,最简单 [root@chensiqi1~]#sed - n '1~2p'person.txt 101,
- chensiqi,
- CEO 103,
- Alex,
- COO 105,
- feixue,
- CIO命令说明:打印文件的1,3,5行。~代表步长 [root@chensiqi1~]#sed - n 'p'person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令说明:不指定地址范围,默认打印全部内容。
- [root@chensiqi1~]#sed - n '/CTO/p'person.txt 102,
- zhangyang,
- CTO命令说明:打印含CTO的行 [root@chensiqi1~]#sed - n '/CTO/,/CFO/p'person.txt 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO命令说明:打印含CTO的行到含CFO的行。
- [root@chensiqi1~]#sed - n '2,/CFO/p'person.txt 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO命令说明:打印第2行到含CFO的行。 [root@chensiqi1~]#sed - n '/feixue/,2p'person.txt 105,
- feixue,
- CIO命令说明:特殊情况,前两行没有匹配到feixue,就向后匹配,如果匹配到feixue就打印此行。所以这种混合地址不推荐使用。
- [root@chensiqi1 ~]# sed -rn '/chensiqi|yy/p' person.txt
- 101,chensiqi,CEO
- 104,yy,CFO
- 命令说明:
- 使用扩展正则"|",为了不使用转义符号"\",因此使用-r选项开启扩展正则表达式模式
- [root@chensiqi1~]#cat person.txt 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO[root@chensiqi1~]#sed - i.bak 's#zhangyang#NB#g'person.txt[root@chensiqi1~]#cat person.txt 101,
- chensiqi,
- CEO 102,
- NB,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO[root@chensiqi1~]#cat person.txt.bak 101,
- chensiqi,
- CEO 102,
- zhangyang,
- CTO 103,
- Alex,
- COO 104,
- yy,
- CFO 105,
- feixue,
- CIO命令行说明:在 - i参数的后边加上.bak(.任意字符),sed会对文件进行先备份后修改
- [root@chensiqi1 ~]# sed '=' person.txt
- 1
- 101,chensiqi,CEO
- 2
- 102,NB,CTO
- 3
- 103,Alex,COO
- 4
- 104,yy,CFO
- 5
- 105,feixue,CIO
- 命令说明:使用特殊符号"="就可以获取文件的行号,这是特殊用法,记住即可。从上面的命令结果我们也发现了一个不好的地方:行号和行不在一行。
- [root@chensiqi1 ~]# sed '1,3=' person.txt
- 1
- 101,chensiqi,CEO
- 2
- 102,NB,CTO
- 3
- 103,Alex,COO
- 104,yy,CFO
- 105,feixue,CIO
- 命令说明:只打印1,2,3行的行号,同时打印输出文件中的内容
- [root@chensiqi1 ~]# sed '/yy/=' person.txt
- 101,chensiqi,CEO
- 102,NB,CTO
- 103,Alex,COO
- 4
- 104,yy,CFO
- 105,feixue,CIO
- 命令说明:
- 只打印正则匹配行的行号,同时输出文件中的内容
- [root@chensiqi1 ~]# sed -n '/yy/=' person.txt
- 4
- 命令说明:只显示行号但不显示行的内容即取消默认输出。
- [root@chensiqi1 ~]# sed -n '$=' person.txt
- 5
- 命令说明:
- "$"代表最后一行,因此显示最后一行的行号,变相得出文件的总行数。
方法改进:
- [root@chensiqi1~]#sed '='person.txt | sed 'N;s#\n# #'1 101,
- chensiqi,
- CEO 2 102,
- NB,
- CTO 3 103,
- Alex,
- COO 4 104,
- yy,
- CFO 5 105,
- feixue,
- CIO命令说明:前面sed获取文件的行号有一个缺点,我们这里使用Sed命令N来补偿这个缺点。Sed命令N读取下一行数据并附加到模式空间。
- [root@chensiqi1~]#sed - n '1p;3p;5p'person.txt 101,
- chensiqi,
- CEO 103,
- Alex,
- COO 105,
- feixue,
- CIO
- [root@chensiqi1 ~]# sed -n '2,4p;=' person.txt
- 1
- 102,NB,CTO
- 2
- 103,Alex,COO
- 3
- 104,yy,CFO
- 4
- 5
- 命令说明:-n去掉默认输出,2,4p,输出2到4行内容,=输出全部的行的行号
- [root@chensiqi1 ~]# sed -n '2,4{p;=}' person.txt
- 102,NB,CTO
- 2
- 103,Alex,COO
- 3
- 104,yy,CFO
- 4
- 命令说明:
- '2,4{p;=}'代表统一输出2,4行的行号和内容
来源: