sed命令
[dmtsai@study ~]$ sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到屏幕上。
但如果加上 -n 参数后,则只有经过 sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令行界面上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以执行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正则表达式的语法。(默认是基础正则表达式语法)
-i :直接修改读取的文件内容,而不是由屏幕输出。
动作说明: [n1[,n2]]function
n1, n2 :不见得会存在,一般代表“选择进行动作的行数”,举例来说,如果我的动作
是需要在 10 到 20 行之间进行的,则“ 10,20[动作行为] ”
function 有下面这些咚咚:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正则表达式!
例如 20s/old/new/g 就是啦!
范例:
范例一:将 /etc/passwd 的内容列出并且打印行号,同时,请将第 2~5 行删除!
[dmtsai@study ~]$ nl /etc/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
.....(后面省略).....
看到了吧?sed 的动作为 ‘2,5d’ ,那个 d 就是删除!因为 2-5 行给他删除了,所以
显示的数据就没有 2-5 行啰~ 另外,注意一下,原本应该是要下达 sed -e 才对,没有 -e
也行啦!同时也要注意的是, sed 后面接的动作,请务必以 ‘’ 两个单引号括住喔!
如果题型变化一下,举例来说,如果只要删除第 2 行,可以使用“ nl /etc/passwd |
sed ‘2d’ ”来达成, 至于若是要删除第 3 到最后一行,则是“ nl /etc/passwd | sed ‘3,$d’ ”的
啦,那个钱字号“ $ ”代表最后一行!
范例二:承上题,在第二行后(亦即是加在第三行)加上“drink tea?”字样!
[dmtsai@study ~]$ nl /etc/passwd | sed '2a drink tea'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(后面省略).....
嘿嘿!在 a 后面加上的字串就已将出现在第二行后面啰!那如果是要在第二行前
呢?“ nl /etc/passwd | sed ‘2i drink tea’ ”就对啦!就是将“ a ”变成“ i ”即可。 增加一行很简
单,那如果是要增将两行以上呢?
范例三:在第二行后面加入两行字,例如“Drink tea or .....”与“drink beer?”
[dmtsai@study ~]$ nl /etc/passwd | sed '2a Drink tea or ......\
> drink beer ?'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(后面省略).....
这个范例的重点是“我们可以新增不只一行喔!可以新增好几行”但是每一行之间
都必须要以反斜线“ \ ”来进行新行的增加喔!所以,上面的例子中,我们可以发现在第一
行的最后面就有 \ 存在啦!在多行新增的情况下, \ 是一定要的喔!
以行为单位的取代与显示功能
刚刚是介绍如何新增与删除,那么如果要整行取代呢?看看下面的范例吧:
范例四:我想将第2-5行的内容取代成为“No 2-5 number”呢?
[dmtsai@study ~]$ nl /etc/passwd | sed '2,5c No 2-5 number'
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
.....(后面省略).....
通过这个方法我们就能够将数据整行取代了!非常容易吧!sed 还有更好用的东
东!我们以前想要列出第 11~20 行, 得要通过“head -n 20 | tail -n 10”之类的方法来处理,
很麻烦啦~ sed 则可以简单的直接取出你想要的那几行!是通过行号来捉的喔!看看下面
的范例先:
范例五:仅列出 /etc/passwd 文件内的第 5-7 行
[dmtsai@study ~]$ nl /etc/passwd | sed -n '5,7p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
上述的指令中有个重要的选项“ -n ”,按照说明文档,这个 -n 代表的是“安静模
式”! 那么为什么要使用安静模式呢?你可以自行下达 sed ‘5,7p’ 就知道了 (5-7 行会重复
输出)! 有没有加上 -n 的参数时,输出的数据可是差很多的喔!你可以通过这个 sed 的
以行为单位的显示功能, 就能够将某一个文件内的某些行号捉出来查阅!很棒的功能!
不是吗?
部分数据的搜寻并取代的功能
除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并取代的功
能喔! 基本上 sed 的搜寻与取代的与 vi 相当的类似!他有点像这样:
sed ‘s/要被取代的字串/新的字串/g’
上表中特殊字体的部分为关键字,请记下来!至于三个斜线分成两栏就是新旧字
串的替换啦! 我们使用下面这个取得 IP 数据的范例,一段一段的来处理给您瞧瞧,让你
了解一下什么是咱们所谓的搜寻并取代吧!
步骤一:先观察原始讯息,利用 /sbin/ifconfig 查询 IP 为何?
[dmtsai@study ~]$ /sbin/ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.100 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::5054:ff:fedf:e174 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:df:e1:74 txqueuelen 1000 (Ethernet)
.....(以下省略).....
# 因为我们还没有讲到 IP ,这里你先有个概念即可啊!我们的重点在第二行,
# 也就是 192.168.1.100 那一行而已!先利用关键字捉出那一行! 、
步骤二:利用关键字配合 grep 撷取出关键的一行数据
[dmtsai@study ~]$ /sbin/ifconfig eth0 | grep 'inet '
步骤三:将 IP 前面的部分予以删除
[dmtsai@study ~]$ /sbin/ifconfig eth0 | grep 'inet ' | sed 's/^.*inet //g'
192.168.1.100 netmask 255.255.255.0 broadcast 192.168.1.255
# 仔细与上个步骤比较一下,前面的部分不见了!接下来则是删除后续的部分,亦即:
192.168.1.100 netmask 255.255.255.0 broadcast 192.168.1.255
# 此时所需的正则表达式为:“ ' *netmask.*$ ”就是啦!
步骤四:将 IP 后面的部分予以删除
[dmtsai@study ~]$ /sbin/ifconfig eth0 | grep 'inet ' | sed 's/^.*inet //g' \
> | sed 's/ *netmask.*$//g'
192.168.1.100
通过这个范例的练习也建议您依据此一步骤来研究你的指令!就是先观察,然后
再一层一层的试做, 如果有做不对的地方,就先予以修改,改完之后测试,成功后再往
下继续测试。以鸟哥上面的介绍中, 那一大串指令就做了四个步骤!对吧! ^_^让我们再来继续研究 sed 与正则表达式的配合练习!假设我只要 MAN 存在的那几
行数据, 但是含有 # 在内的注解我不想要,而且空白行我也不要!此时该如何处理呢?
可以通过这几个步骤来实作看看:
步骤一:先使用 grep 将关键字 MAN 所在行取出来
[dmtsai@study ~]$ cat /etc/man_db.conf | grep 'MAN'
# MANDATORY_MANPATH manpath_element
# MANPATH_MAP path_element manpath_element
# MANDB_MAP global_manpath [relative_catpath]
# every automatically generated MANPATH includes these fields
....(后面省略)....
步骤二:删除掉注解之后的数据!
[dmtsai@study ~]$ cat /etc/man_db.conf | grep 'MAN'| sed 's/#.*$//g'
MANDATORY_MANPATH /usr/man
....(后面省略)....
# 从上面可以看出来,原本注解的数据都变成空白行啦!所以,接下来要删除掉空白行
[dmtsai@study ~]$ cat /etc/man_db.conf | grep 'MAN'| sed 's/#.*$//g' | sed '/^$/d'
MANDATORY_MANPATH /usr/man
MANDATORY_MANPATH /usr/share/man
MANDATORY_MANPATH /usr/local/share/man
....(后面省略)....
直接修改文件内容(危险动作)
你以为 sed 只有这样的能耐吗?那可不! sed 甚至可以直接修改文件的内容呢!而
不必使用管线命令或数据流重导向! 不过,由于这个动作会直接修改到原始的文件,所
以请你千万不要随便拿系统配置文件来测试喔! 我们还是使用你下载的
regular_express.txt 文件来测试看看吧!
范例六:利用 sed 将 regular_express.txt 内每一行结尾若为 . 则换成 !
[dmtsai@study ~]$ sed -i 's/\.$/\!/g' regular_express.txt
# 上头的 -i 选项可以让你的 sed 直接去修改后面接的文件内容而不是由屏幕输出喔!
# 这个范例是用在取代!请您自行 cat 该文件去查阅结果啰!
范例七:利用 sed 直接在 regular_express.txt 最后一行加入“# This is a test”
[dmtsai@study ~]$ sed -i '$a # This is a test' regular_express.txt
# 由于 $ 代表的是最后一行,而 a 的动作是新增,因此该文件最后新增啰!
使用sed来永久关闭selinux
sed -i ‘s/SElINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/config
sed -i ‘7s/enforcing/disabled/g’ /etc/selinux/config
printf (使用的比较少)
[dmtsai@study ~]$ printf '打印格式' 实际内容
选项与参数:
关于格式方面的几个特殊样式:
\a 警告声音输出
\b 倒退键(backspace)
\f 清除屏幕 (form feed)
\n 输出新的一行
\r 亦即 Enter 按键
\t 水平的 [tab] 按键
\v 垂直的 [tab] 按键
\xNN NN 为两位数的数字,可以转换数字成为字符。
关于 C 程序语言内,常见的变量格式
%ns 那个 n 是数字, s 代表 string ,亦即多少个字符;
%ni 那个 n 是数字, i 代表 integer ,亦即多少整数码数;
%N.nf 那个 n 与 N 都是数字, f 代表 floating (浮点),如果有小数码数,
假设我共要十个位数,但小数点有两位,即为 %10.2f 啰!