sed
sed:默认情况下不编辑原文件,而是提取需要处理的行到内存的模式空间去编辑,并且显示出来.
地址块和命令之间没有空格
- 地址块有下面几种方法定义:
1.起始行,结束行
比如:1,100———表示第1,到第100行
$表示最后一行
+表示后续的行.比如1,+2 表示第1行,以后第2,3行
2./正则表达式/
比如:/^root/ ———表示以root为起始的行
3./pattern1/,/pattern2/
表示第一次被pattern1匹配到的行开始,到第一次被pattern2匹配到的行结束的中间所有行
4. /pattern/ 表示精准匹配pattern的所有行..
注意:模式匹配需要双斜杠/ /把字符圈起来
sed用法
sed [option] ———-sed的选项,可以省略
-n 使用安静模式,不输出模式空间中内容到屏幕
-e 直接在命令行模式上进行动作编辑
-f 直接将sed的动作写在一个文件内
-r 支持扩展型正则表达式
-i 直接修改读取的文件内容,不是由屏幕输出
n1,n2:不一定会存在,一般代表选择进行动作的行数.例如.如果是在10行和20行之间进行,那就是10,20
Command命令
a: 新增, a后面可以接字符串,而这些字符串会再新的一行出现
c: 替换,c后面可以接字符串,这些字符串可以替换n1,n2之间的行
d: 删除,因为是删除,所以d后面通常不接任何参数
i: 插入,i的后面可以接字符串,而这些字符串会再新的一行出现
p:打印,也就是讲某个选择的数据打印出来,通常会与参数-n 一起执行
s: 替换,可以直接进行替换的工作,通常这个s的动作可以搭配正则表达式!
!: 取反
1.默认情况下,只替换每行中第一次匹配到的字符串.加上修饰符g,则表示如果行中还有其他也能匹配则继续替换.例如:
1,20s/old/new/g
2.默认情况下可以使用/作为分隔符,当然也可以使用其他符号作为分隔符.比如:s#old#new#.或者s@old@new@
3.s/pattern/string/ 前面可以用正则表达式查找模式.但是替换后的字符串,则不能使用正则表达式
sed用法例子:
基础用法:
注意,sed的动作,需要2个单引号括住:
[root@localhost ~]$nl /tmp/passwd | sed '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
1 | [root@localhost ~]$nl /tmp/passwd | sed '3,$d' |
在第二行后面新增一行
1
2
3
4
5[root@localhost ~]$nl /tmp/passwd | sed '2a this is a new line'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
this is a new line
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin在第二行前新增,并且新增2行
1
2
3
4
5
6[root@localhost ~]$nl /tmp/passwd | sed '2i this is a line before 2 \
> continue a line '
1 root:x:0:0:root:/root:/bin/bash
this is a line before 2
continue a line
2 bin:x:1:1:bin:/bin:/sbin/nologin将2-5行内容替换成为”no 2-5 number”
1 | [root@localhost ~]$nl /tmp/passwd | sed '2,5c no 2-5 number' |
1 | [root@localhost ~]$nl /tmp/passwd | sed -n '2,5p' |
sed直接修改文件
-i 参数.. 代表直接修改文件,而不输出到屏幕上
- 例如:将下列文件中的小数点换成逗号
1
2
3
4
5[root@www tmp]$cat 2.txt
haha....sed
[root@www tmp]$sed -i 's/\./,/g' 2.txt
[root@www tmp]$cat 2.txt
haha,,,,sed
替换用法
格式: sed ‘s/要被替换的字符串/新的字符串/g’
抓取IP地址:1
2[root@www ~]$ifconfig eth0 | grep "inet addr"
inet addr:172.16.1.120 Bcast:172.16.1.255 Mask:255.255.255.0
sed删除.^.*addr: 代表任意字符开头的,addr:结尾的字符串. //代表空
1 | [root@www ~]$ifconfig eth0 | grep "inet addr" | sed 's/^.*addr://g' |
删除Bcast的后半部分
1 | [root@www ~]$ifconfig eth0 | grep "inet addr" | sed 's/Bcast.*$//g' |
只保留IP,其余部分删除
1 | [root@www ~]$ifconfig eth0 | grep "inet addr" | sed 's/Bcast.*$//g' | sed 's/^.*addr://g' |
删除以#开头的,以及空白行
1 | [root@www ~]$cat /etc/man.config | grep 'MAN' | sed 's/^#.*$//g' | sed '/^$/d' |
马哥的Linux视频sed练习
以下是原文
1 | hello world |
1 | [root@www tmp]$sed 's/^[[:space:]]*//g' test.txt |
1 | [root@www tmp]$sed 's/id:3:initdefault:/id:5:initdefault:/' test.txt |
1 | [root@localhost ~]$sed '/^$/d' /tmp/test.txt |
1 | [root@localhost ~]$sed 's/^#//g' /tmp/test.txt |
解释:这里用两个空格字符,是表示#空格然后再重复前面的空格0次或者多次.
如果是sed ‘s/^#[[:space:]]//‘ sed.txt 则表示空格字符可以是0次,也可以是无穷次,会把上面两行#i love you一起删除
1 | [root@localhost ~]$sed 's/^#[[:space:]][[:space:]]*//g' /tmp/test.txt |
或者可以用扩展正则
1 | [root@localhost ~]$sed -r 's/^#[[:space:]]+//g' /tmp/test.txt |
NOTE:扩展正则需要加上-r参数
1 | [root@localhost ~]$sed -r 's/^[[:space:]]+#//g' /tmp/test.txt |
sed位置替换
sed在替换的时候支持位置参数.比如看下面2个例子:
1.将下列所有以_all结尾的单词前面加个>破折号.
1 | cat test |
1 | [root@localhost tmp]$sed -r 's@(.*)_all$@\1>_all@g' pos.txt |
解析 sed -r ‘s@(.*)_all@>\1_all@g’:
-r 表示扩展正则,这里虽然没有用到扩展正则表达式,但是位置变量替换本身就是扩展正则
(.) 表示匹配任意字符
\1 表示代替前面的第一个(.)正则表达式..也就是说把前面这个.匹配到的所有内容放在\1这个位置上.
所以这个语句表示:匹配任意以_all结尾的字符串,然后保留\1分组匹配到的(.\)内容不变,只是在_all前面加个>破折号
所以前面.*匹配到的fsdafdsa,weewwe,haha会被放置在>破折号后面,_all之前.
2.将一个文件中的taomee、**、peoplenet中的内容进行替换成network(的内容不同)
1 | [root@localhost tmp]$echo "taomee,stage,peonetwork" > 1.txt |
解析: sed -ri ‘s#(.),.{5},(.)#\1,network,\2#g’
.{5} .代表一个任意字符,{5}表示重复前一个匹配5次,这里就是匹配5个任意字符
\1 表示第一个正则匹配的内容放入的位置.这里表示第一个.
\2 表示第二个正则匹配的内容放入的位置,这里表示第二个.
network:表示.{5}匹配的内容,替换成network
所以这里就是表示下列各式的内容:任意字符 5个任意字符 任意字符 然后把中间5个任意字符替换成network
3.将下列 database_host: 10.0.0.10的IP改成10.0.0.2:
1 | work@docker$ cat parameters.yml |
1 | sed -re '/database_host:/s#(:\s*).+$#\110.0.0.2#' parameters.yml |
解析:/s#(:\s*).+$#\110.0.0.3# :
\1表示匹配第一个分组
(:\s*)所匹配到的内容保留下来.也就是保留:和10这中间的空格部分
10.0.0.2代替.+匹配到的内容,也就是用10.0.0.2替代匹配到的10.0.0.10