bash--使用sed命令

sed (流文本编辑器)

    用法:sed OPTIONS... [SCRIPT] [INPUTFILE...]
        -r: 使用扩展的正则表达式; 
        -n, --quiet, --silent: 不输出模式空间的内容;
        -i:直接编辑原文件;
        -e: -e '' -e '' -e ''
            'CMD1;CMD2;CMD3'
        # sed -e '1d' -e '2p' /etc/fstab
        # sed '1d;2p' /etc/fstab #同时执行多条命令
        -f /path/to/sed_script:从指定的文件读取处理脚本

sed 工作流程

工作流程:把文本中第一行读取到模式空间(内存)--在模式空间内进行编辑(script)--输出编辑后的内容--清空模式空间(再循环到第一步)

地址定界:

#(行号): 指定行
$: 最后一行
/regexp/:任何能够被regexp匹配到的行 # sed '/dev/d' /etc/fstab #删除匹配到dev的行
\%regexp%: 任何能够被regexp匹配到的行;换用%为边界符号;# sed '\%/dev/mapper%d' /etc/fstab #删除匹配到/dev/mapper的行。边界匹配可以换成@,#等,但必须是@开头和@结尾
/regexp/I  # sed '/dev/Id' /etc/fstab
\%regexp%I:匹配时忽略字符大小写;
      addr1, addr2: 指定范围内的所有行:
1·,/regexp/    
#(行号),#(行号)
 /regexp/,/regexp/
#(行号),+# :假如#=2,则+#等于加后面2行 # sed '2,+2d' /etc/fstab,删除第2行开始,到第4行匹配到的内容
first~step:指定起始位置,以及步长 1~3 # sed '1~2d' /etc/fstab

基本正则表达式元字符:

字符:.  []  [^]
次数:*, +, ?, {i,j}
分组:()
锚定:^, $, <, >
或者:|
后向引用:1, 2, ...

编辑命令:

注意:命令之前可以使用!表示取反操作;
 =: 显示行号
   # sed -n '\%/dev/mapper%=' /etc/fstab #打印匹配到/dev/mapper的行号
d: 删除匹配到的行;
p: 打印模式空间中的内容;
   通常与-n选项一同使用;
   # sed -n '3,5p' /etc/fstab #输出第3到5行,如果不加-n参数,第3到5行会打印2遍
a 	ext: append, # sed '1a 	est' /etc/fstab
a 	ext1
text2
text3: 附加多行文本
i 	ext:insert, 
   i 	ext1
text2: 插入多行文本
c 	ext: change,把匹配到的行替换为给定的文本
   # sed '3c mmmm' /etc/fstab #把文件第3行替换成mmmm,一整行替换
s///: 替换命令
    g: 全局替换
    i: 不区分大小写
    # sed 's/dev/etc/g' /etc/fstab #将文件中dev替换为etc

实例:

1 删除/boot/grub/grub.conf文件中所以空白开头的行行首的空白
# sed 's/^[[:space:]]+//g' /boot/grub/grub.conf
2 删除/etc/fstab文件中所有以#开头,后跟至少一个空白字符的行的行首的#和空白字符
# sed 's/^#[[:space:]]+//' /etc/fstab
3 echo一个文件路径给sed命令,取出其基名;取出其目录名
# echo "/etc/sysconfig/" | sed 's@[^/]{1,}/?$@@g'
4 替换/etc/inittab文件“id:数字:initdefault:”一行中的那个数字为6
# sed 's@id:[0-9]:initdefault:@id:6:initdefault@' /etc/inittab

高级编辑命令:

 h: 用模式空间中的内容覆盖保持空间中的内容;
 H:把模式空间中的内容追求至保持空间;
 g: get, 从保持空间取回数据至模式空间,覆盖模式空间中原有的内容;
 G:GET, 从保持空间取回数据至模式空间,追加于模式空间中现有的内容后面;
 x: 把模式空间和保持空间中的内容进行交换;
 n: 读取匹配到的行下一行至模式空间;
 N: 追加读匹配到的行下一行至模式空间;
 d: 删除模式空间中的内容;
 D:删除多行模式空间中首行;
sed '1!G;h;$!d' FILE
#解释:取文件第一行,第一行不执行G命令(其他行要执行G命令);执行h命令;最后一行不执行d命令(不是最后一行都要执行d命令),循环每一行

显示文件的偶数行:

[root@iscsi ~]# cat aa
aa
bb
cc
dd
mm
命令:sed -n 'n;p' FILE;   或者  sed -n '2~2p' FILE
[root@iscsi ~]# sed -n 'n;p' aa
bb
dd
[root@iscsi ~]# sed -n '2~2p' aa
bb
dd

显示文件的奇数行:

命令:sed -n 'p;n' FILE;     sed -n '1~2p' FILE
[root@iscsi ~]# sed -n 'p;n' aa
aa
cc
mm
[root@iscsi ~]# sed -n '1~2p' aa
aa
cc
mm

运用 sed 命令高效地删除文件的特定行

注意:-i 表示直接进行文件操作,而不在终端上显示结果。
1 删除某一行 sed 'Nd' file
# sed '1d' sed_test.ext
# sed '$d' sed_test.txt 删除最后一行
2. 删除某些行
# sed '5,7d' sed_test.txt #删除5,6,7行
# sed '1d;5d;9d;$d' sed_test.txt #删除不连续的行
# sed '3,6!d' sed_test.txt #删除第 3到 6 行以外的其他行
3. 删除空白行
# sed '/^$/d' sed_test.txt #这里两个斜杠 / / 内的表达式起到了文本匹配的作用
4. 删除包含特定字符的行
# sed '/System/d' sed_test.txt 
# sed '/System|Linux/d' sed_test.txt  #符号 | 代表逻辑或,文本中有 System 或 Linux 的行都要进行删除。
5. 删除特定字符开头的行
# sed '/^R/d' sed_test.txt  #删除已R开头的行
# sed '/^[RF]/d' sed_test.txt  #删除以 R 或者 F 开头的行
6. 删除特定字符结尾的行
# sed '/m$/d' #删除以m结尾的行
# sed '/[xm]$/d' #删除以X或m结尾的行
7. 删除以大写字母开头的行
# sed '/^[A-Z]/d'
8. 删除包含字母字符的行
# sed '/[A-Za-z]/d'
9. 删除包含数字的行
# sed '/[0-9]/d'
# sed '1,6{/Linux/d;}' #指定删除在 1 到 6 行内有 Linux 这个词的内容
# sed '/System/{N;d;}' #删除包含 System 以及其下一行的内容

练习:说明以下sed命令的意义:

(1) sed '$!N;$!D' /etc/issue
(2) sed '$!d' /etc/issue #最后一行不执行删除命令,即删除最后一行之前的行
(3) sed 'G' /etc/issue #每行后面加空白行
(4) sed '/^$/d;G' /etc/issue
(5) sed 'n;d' /etc/issue #删除偶数行
(6) sed -n '1!G;h;$p' /etc/issue
原文地址:https://www.cnblogs.com/yhq1314/p/13691734.html