Linux sed工具基础用法小结

sed即stream editor,意译为“流式编辑器”。它是Linux中三大文本处理工具(grep、sed、awk)之一,其功能非常强大,以至于能写一篇超长的文章来分析它。不过这里就长话短说(其实是我水平有限),只记录一下它的基础用法。

sed工作流程

sed每次从输入源取得一行文本,并存入模式空间(英文pattern space)。然后,根据设定好的地址命令(这两个概念下面会提到),对模式空间内的文本进行转换,再将转换后的文本输出。也就是说,sed是一个非交互式的文本编辑器,而不像vim一样是交互式的。

sed调用语法

如同上图中Dash的man page中显示的,其语法是:

sed [-Ealn] [-e command] [-f command_file] [-i extension] [file...]

  • -E:启用扩展正则表达式(ERE),ERE支持?、+和|元字符,还有其他一些特性。如果不启用的话,sed默认会使用基本正则表达式(BRE)来做匹配。关于BRE和ERE参见维基:https://en.wikipedia.org/wiki/Regular_expression#Standards。
  • -n:只将匹配到的行输出到stdout,而非所有行。一般和p命令搭配使用,见下方。
  • -e:指定一条sed命令,默认可以不写。但如果需要对输入文本进行多种转换,就需要指定多个-e参数。
  • -f:从文件中读入多条sed命令。
  • -i:将结果输出到文件,而不是打印到stdout。如果直接使用-i,就会覆盖写入源文件,比较危险,因此建议输出到备份,如-i.bak。

sed定址

默认情况下,sed会处理输入源中的每一行文本。但大多数情况下我们只需要处理一部分内容,这时就需要指定地址了。

地址总是会出现在命令的前面,一般是采用数字行号的方式定址。下面的例子会先涉及到命令p,即直接打印,也是sed中最经常使用的命令之一。

  • 将/etc/passwd中第7行输出
    sed -n '7p' /etc/passwd
  • 将第7~12行输出
    sed -n '7,12p' /etc/passwd
  • 从第7行开始,往后数5行,将这些行输出
    sed -n '7,+5p' /etc/passwd
  • 从第7行开始,每隔5行,将这些行输出
    sed -n '7~5p' /etc/passwd
  • 将除了第7行的内容输出
    sed -n '7!p' /etc/passwd

除了数字行号定址之外,也可以采用正则匹配定址。下面的例子涉及到了命令d,即删除。

  • 将/etc/passwd中匹配到var的行删除
    sed '/var/d' /etc/passwd
  • 将空行删除,注意^在BRE中匹配行首,而$在BRE中匹配行尾
    sed '/^$/d' /etc/passwd
  • 将含有三位及以上数字的行到以false结尾的行中间所有行都删除
    sed -E '/[0-9]{3,}/,/false$/d' /etc/passwd

sed命令

命令就是sed中对输入文本进行处理的规则,下面介绍常用的。

  • 命令p
    上面已经介绍过了。
  • 命令a和i
    a表示在定址行的下面插入字符串,而i则表示在定址行的上面插入字符串。
    将/etc/passwd中7~12行每行下面插入2行LM:
    sed '7,12a LM\nLM' /etc/passwd
  • 命令c
    c表示把定址行内容替换成目标内容。
    将/etc/passwd中7~12行替换成LM,注意是所有行作为整体一起替换,而不是每一行:
    sed '7,12c LM' /etc/passwd
  • 命令d
    d表示将定址行删除,上面已经演示过了它的用法。采用行号定址的方法相同,不再赘述。注意如果不定址,sed 'd' /etc/passwd会删除全部内容。
  • 命令y
    y表示替换字符,不支持正则表达式,但可以同时替换多个字符。
    将/etc/passwd中a替换成1,b替换成2:
    sed 'y/ab/12/' /etc/passwd
  • 命令r和w
    r表示在一个文件中读取内容,并追加在定址行后面。w则表示将模式空间里的内容追加在文件后面。
    将temp.txt中的内容追加在/etc/passwd最后:
    sed '$r temp.txt' /etc/passwd
  • 命令s
    s命令是sed的精髓所在,表示按正则表达式替换。它的格式是s/[regexp]/[replace]/[flags]。flags有以下4种:
    • n:一个数字,1~512之间,表示每行第n次出现时替换;
    • g:替换所有出现的情况。如果n和g都不指定,就是替换第1个;
    • p:打印模式空间的内容到stdout;
    • w:追加模式空间的内容到文件中。

举例:

  • 将/etc/passwd中所有'/bin/bash'替换成spark:
    sed 's/\/bin\/bash/spark/g' /etc/passwd
  • 将每行第二个usr或者bin或者var删除:
    sed -E 's/(usr|bin|var)//2' /etc/passwd
  • 将每行中第一个大写字母开头的英文单词前后各加3个空格。replace字符串中,&表示匹配出的结果集:
    sed -E 's/[A-Z][a-z]+/ & /' /etc/passwd
  • 按冒号分隔,将所有奇数行中第3个域和第1个域输出。replace字符串中,\k表示匹配第k个分组:
    sed -n -E '1~2s/([^:]*):([^:]*):([^:]*).*/\3\t\1/p' /etc/passwd

你可能感兴趣的:(Linux sed工具基础用法小结)