[shell]sed-迁
1 命令模式
1.1 编辑命令模式
 格式 sed [options] 'command' file(s)
command 部分:[地址1,地址2][函数][参数]
 1.1.1 一个或两个地址是可以省略的
 1.1.2 可以用任何数目的空白或tab把地址和函数分隔开
 1.1.3 函数必须出现
 1.1.4 依据给出的是哪个函数,标记可能是必需的或者是可选的
 1.1.5 引用shell变量时要使用双引号,而不是通常所用的单引号
 
1.2 脚本模式
格式 sed [options] -f scriptfile files
 1.2.1 脚本是一个sed的命令清单
 1.2.2 在命令的结尾不能有任何的空白或文本
 1.2.3 如果一行中有多个命令,要用分号分隔
 1.2.4 不需要且不能用引号保护命令
 1.2.5 以#开头的行为注释,且不能跨行
/western/,/southease/{
/^$/d
/Suan/{h;d}
}
/Ann/g
s/TB \(Savage\)/Thomas \1/
#去掉空行 sed /^$/d file
1.3 options 部分(命令行标志)
-e 下一个参数接受为编辑命令,允许多项编辑
sed -e '1,3d' -e 's/west/north/' file
注意:
多个命令都在模式空间的当前行上执行
编辑命令的顺序会影响结果
- -i 直接修改目标文件
- -f 把下一个参数接受为脚本名,这个文件应当包含一行一个的编辑命令
- -n 不输出所有行,只复制p函数或在s函数后p标志所指定的行
2 多输入行
- D 删除当前模式空间中直到并包括第一个换行字符的所有字符
- N 追加下一个输入行到模式空间后面合并在两者间嵌入一个换行符,改变当前号码模式匹配可以延伸跨越这个内嵌换行
- P 打印模式空间中的直到并包括第一个换行的所有字符
- q 结束或退出sed
- l 列出非打印字符
3 定址
删除第一行,十进制数
sed '1d' file
正则表达式
sed '/john/d' file #删除包含john的行 sed '/^john/d' file #删除john打头的行
注意使用特殊字符(^ $ . * [ ] \ /) 都要用 \ 来转义字符
逗号分隔符
sed '1,3d' file #删除第一行和第三行之间的范围 sed '/west/,/east/d' file #删除west和east之间的行
组合方式
sed '1,/west/d' file #第一行开始到west之间的所有行
特殊情况
sed '$d' file #字符 $ 匹配最后一个
sed 特殊格式
sed -n '2p' #只输出第二行 sed -n '0,/west/p' file #从第一行开始匹配到west为止 sed -n '/west/,+2p' file #匹配west后,再操作west后N行 sed -n '/west/,~6' file #匹配west后再操作到N的倍数的行为止 sed -n '0~5p' file #从0行开始每5行操作一次 sed -n '/west\|esat/p' file #匹配模式west和east
4 正则表达式
行首定位符
/^love/
行尾定位符
/love$/
匹配除换行符外的单个字符
/l..e/
匹配0个或多个前一字符
/*love/
匹配指定字符组内的任一字符
/[Ll]over/
匹配不在指定字符组内的任一字符
匹配包含over,但over之前的那个字符不在 A到K或M到Z之间的行 /[^A-KM-Z]over/
保存被匹配的字符
最多可以使用9个标签,模式中最左边的标签是第一个,本例:模式love被保存为标签 \1,以后可引用为 \1,
这个例子中,查找字符串是love后面跟着r替换成loveable
echo "my deer lover"|sed 's/\(love\)r/\1able/' 
my deer loveable
取前11个字符,用到了\1的方法和取字符的方法,通awk的substr($1,1,11)
echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -rn 's/^(.{11}).*/\1/p'
! in the we
 want to li
 east use n
词首定位
/\<love/
词尾定位
/love\>/
连续m个字符x
匹配连续出现5个o的行 /o\{5\}/   x\{\m}
至少m个的x x\{m,\}
至少m个但不超过n个的x x\{m,n\}
5 函数
插入、修改、删除
a\
在当前行后添加一或多行 ,a后面第二个反斜杠用来被shell转义为换行符
echo "my deer lover"|sed '/^my/a\\ -->test<--' my deer lover -->test<-- #35行增加一条数据,并将原文件重命名 sed -i_bak '35 a \mongodb = 192.168.100.65:50005' config.ini #最后一行插入[append] sed "$ a test" my.txt #追加内容 sed -i '/^root.*ALL$/a nagios ALL=(ALL) NOPASSWD: ALL' /etc/sud oers #行前加 sed -i '/allow chengyongxu.com/i\allow chengyongxu.cn' the.conf.file #行前后 4sed -i '/allow chengyongxu.com/a\allow chengyongxu.cn' the.conf.file
i\
在当前行上添加一或多行
第二行插入[insert] sed "2 i test" my.txt
d
删除第3行
sed '3d' file
匹配到,删除其后3行
sed '/lotterycore-1-1/,+3d' /etc/salt/roster
查找替换
c
匹配到后,整行操作
#修改第28行 sed -i '28 c \fudge 134.98.5.80 stratum 10' /etc/ntp.conf #匹配到dog,如果匹配整行到就替换为test000000 sed "/dog/c test000000" my.txt
s
匹配到后,只对匹配部分操作
sed 's/west/north/g' file 将west替换成north,后面的g表示全局替换 sed 's#west#north#g' file 使用 "#" 替换默认分隔符"/" ,仅在使用s命令时 sed "s/$Old_url/$New_url/g" $salt_dir/yixin_index.js|grep "http" 遇到变量的参数,需要将 ' 改为 " ' #匹配到west,后面空格可以用正则表达式处理替换,-n p只打印做操作那行 echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -n 's/west\+.i/123\ /p' ! in the 123 42 sed 's/west/[&]/' #只对匹配到west做修改 ! in the [west] i42 去掉 ^M ^M是使用 "CTRL-V CTRL-M" sed -e "s/^V^M//" 或者 %s/^M//g 利用for和grep -v反向匹配,循环sed 注意,遇到中文字符sed会卡住! for i in `ls|grep -v ^img`;do echo $i; sed -i 's/\.+/\\S+/' $i;done
多次匹配用; 号隔开
sed -i "s/1-1.salt/10.4.230.2/;s/10.4.234.1/10.4.230.2/
先匹配再对整行修改替换
#匹配在west和east之间,行的最后替换为**vava** echo -e "! in the west i\n want to listen the radio\n east use nothing\n just"|sed '/west/,/east/s/$/**vava**/' ! in the west i**vava** want to listen the radio**vava** east use nothing**vava** just # 匹配到west然后头加# sed /west/'s/^/# /' # ! in the west i42 #匹配到west后行尾加@ecp sed /west/'s/.*/&@ecp/' ! in the west i42@ecp #匹配到west后行首加@ecp sed /west/'s/X*/&@ecp/' @ecp! in the west i42
所有以两位数字结尾的行后面都被加上.5,怎么变成两行了??
echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed 's/[0-9][0-9]$/&444/p' ! in the west i42444 ! in the west i42444 want to listen the radio east use nothing88444 east use nothing88444 just
匹配到后修改本行及其后两行
echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed '/west/,+2s/^/# /g' # ! in the west i42 # want to listen the radio # east use nothing88 just
保存和取回
hold space == 暂存空间
pattern space == 模式空间
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
匹配到west的行,放入暂存区(只保留最后一次操作),然后追加到文件的最后 echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -e '/west/h' -e '$G' ! in the west i42 want to listen the radio east use nothing88 just ! in the west i42
H: 将pattern space中的内容append到hold space\n后
匹配到west的行,放入暂存区,然后追加到文件的最后 $ echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -e '/west/H' -e '$G' ! in the west i42 want to listen the radio east use nothing88 just ! in the west i42
g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
匹配到east,把east拷贝到模式空间然后删掉,匹配所有west行,删掉
echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -e '/east/{h;d;}' -e '/west/{g;}'
 want to listen the radio
 just
 
G: 将hold space中的内容append到pattern space\n后
匹配到west的行,会被拷贝到暂存空间,并删除,然后被追加到文件的最后一行
$ echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -e '/west/{h;d}' -e '$G'
 want to listen the radio
 east use nothing88
 just
! in the west i42
x: 交换pattern space和hold space的内容
包含east的行,会被west这行替换掉 echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -e '/west/h' -e '/east/x' ! in the west i42 want to listen the radio ! in the west i42 just
经典的是将文件格式进行整理
举例:
$ cat /tmp/1 1-line 2-line 3-line $ sed '2,$G;h;$!d' /tmp/1 3-line 2-line 1-line $ echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed -e '2,$G' -e 'h' -e '$!d' just east use nothing88 want to listen the radio ! in the west i42
扫描到第一行
- 将1-line放入pattern space;此时pattern space还是1-line;
- 直接执行h命令,此时hold space是1-line;
- 执行d命令,删除了pattern space仅有的一行数据,删除之后,pattern space是空的
扫描到第二行
- 将2-line放入pattern space
- 执行G命令,将hold space的1-line添加到pattern space的2-line的后面,此时pattern space是2-line\n1-line;
- 执行h命令,此时hold space的内容是2-line\n1-line;
- 执行d命令,pattern space被清空
扫描到第三行
- 将3-line放入pattern space,
- 执行G命令,将hold space的2-line\n1-line添加到pattern space的3-line的后面,此时pattern space是3-line\n2-line\n1-line;
- 执行h命令,此时hold space的内容是3-line\n2-line\n1-line;
- $!d 到结尾不执行清空操作;
直接输出 3-line\n2-line\n1-line
2,$G:从第二行到最后一行执行G命令 h:执行h命令 $!d:删除除了最后一行的所有行
输入输出
p 打印行
sed -n '/west/p' file 只打印匹配west的行 sed -n '/west/,/east/p' file 打印模式west和east之间的所有行 sed -n '5/east/p' file 打印5到east之间的行
r 从文件中读取输入行
匹配到east,然后输入文件FileRecv/id_rsa.pub echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed '/east/r FileRecv/id_rsa.pub' ! in the west i42 want to listen the radio east use nothing88 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNPbxNWoQdIGH1eQnwC+1wY6CXronVyrnkPtFH10 just
w 将行写入文件
匹配到east然后把这行写入到文件 echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed '/east/w /tmp/myfile' ! in the west i42 want to listen the radio east use nothing88 just richard@richard-PC:~$ cat /tmp/myfile east use nothing88
控制流
!对所选行以外的所有行应用命令
只保留包含john的行 sed -n '/john/!d' file
{} 组合命令
一组命令作为一个块而被应用
函数命令之间用分号分割
组合可以嵌套
删除west到east之间行,然后把Suan那行保存到暂存模式,然后参数
sed -n '/west/,/east/{/^*/d;/Suan/{h;d;}}' 
n 读入下一输行,并从下一条命令,而不是第一条命令开始对其
echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|sed '/west/{n;s/want/bye/;}'
! in the west i42
 bye to listen the radio
 east use nothing88
 just
函数列表
| 函数参数 | 功能 | 
|---|---|
| :label | 建立脚本内指令跳转的参考位置 | 
| # | 添加注释 | 
| {} | 集合有相同地址参数的命令 | 
| ! | 不执行函数参数 | 
| = | 印出资料行数 | 
| a\ | 添加使用者输入的数据 | 
| b label | 将执行的指令跳转至:label | 
| c\ | 以使用者输入的数据取代数据 | 
| d | 删除数据 | 
| D | 删除pattern space内第一个neweline字母\前的数据 | 
| g | 拷贝数据从hold space | 
| G | 添加资料,从hold space到pattern space | 
| h | 拷贝资料,从pattern space到hold space | 
| H | 添加资料,从pattern space到hold space | 
| l | 用ASCII码印出1资料中nonprinting character | 
| i\ | 插入添加使用者输入的数据行 | 
| n | 读取下一笔资料 | 
| N | 添加下一笔资料到pattern space | 
| p | 打印资料 | 
| P | 打印pattern space内第一个newline 字母\前的数据 | 
| q | 跳出sed编辑 | 
| r | 读入文档内容 | 
| s | 替换字符串 | 
| t label | 先执行一替换的编辑指令,如果替换成p>,则将编辑指令跳转至:label处执行 | 
| w | 往文档内写入资料 | 
| x | 交互hold space和pattern space内容 | 
| y | 转换(transform)字符 | 
echo -e "! in the west i42\n want to listen the radio\n east use nothing88\n just"|python sedsed -d --hide=hold ':f;N;/radio/!bf;s/\n/\ /g'
函数解析
将radio结尾的行,上提到上面行尾
PATT:! in the west i42$ COMM::f COMM:N PATT:! in the west i42\n want to listen the radio$ COMM:/radio/ !b f COMM:s/\n/\ /g PATT:! in the west i42 want to listen the radio$ ! in the west i42 want to listen the radio PATT: east use nothing88$ COMM::f COMM:N PATT: east use nothing88\n just$ COMM:/radio/ !b f COMM:N east use nothing88 just
sed ':a;N;/success/!ba;s/\n/\ /g' test 以success为终点,读取处理文件块,然后再将换行改为空格
 

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号