跳到内容

sed 命令

sed:流编辑器

工作原理sed 命令会读取当前处理的行,并将它放到“模式空间”进行处理。处理完成后,结果会输出,并且“模式空间”会被清空。接下来读取下一行,并将其放到“模式空间”进行处理,以此类推,直到最后一行。有些文档还会提到一个叫做“保持空间”(也称为“临时存储空间”)的概念,它可以临时存储一些处理过的数据,并通过“模式空间”输出。

“模式空间”和“保持空间”:内存中的一个区域,用于处理和存储数据。

对于未涵盖的信息,请查看sed 手册

命令的使用方法是

sed [OPTION]... {script-only-if-no-other-script} [input-file]...
选项描述
-n仅将 sed 命令处理过的文本行输出到屏幕
-e将多个 sed 操作命令应用于输入文本行数据
-f调用并执行 sed 脚本命令文件
-i修改原始文件
-r正则表达式
操作命令
(有时称为操作指令)
描述
s/regexp/replacement/替换字符串
p打印当前“模式空间”。通常与 -n 选项一起使用,例如:cat -n /etc/services \| sed -n '3,5p'
d删除“模式空间”。开始下一个循环
D删除“模式空间”的第一行,并开始下一个循环
=打印行号
a \text在匹配行之后添加一行或多行内容。添加多行时,除了最后一行之外,所有行都需要使用“\”来表示内容尚未结束
i \text在匹配行之前添加一行或多行内容。添加多行时,除了最后一行之外,所有行都需要使用“\”来表示内容尚未结束
c \text用新文本替换匹配行
q立即退出 sed 脚本
r附加从文件读取的文本
: label用于 b 和 t 命令的标签
b label分支到标签;如果省略标签,则分支到脚本末尾
t label如果“s///”是成功的替换,则跳转到标签
h H将“模式空间”复制/追加到“保持空间”
g G将“保持空间”复制/追加到“模式空间”
x交换保持空间和模式空间的内容
l以“视觉上明确”的方式列出当前行
n N将输入的下一行读取/附加到“模式空间”
w FILENAME将当前模式空间写入 FILENAME
!否定
&引用已经匹配的字符串
地址描述
first~step使用“first”指定第一行,使用“step”指定步长。例如,使用 sed -n "1~2p" /etc/services 输出文本的奇数行
$匹配文本的最后一行
/regexp/使用正则表达式匹配文本行
number指定行号
addr1,addr2使用行号定位来匹配从“addr1”到“addr2”的所有行
addr1,+N使用行号定位来匹配 addr1 和 addr1 之后的 N 行

使用示例

  1. 匹配并打印(p

    • 打印以 netbios 字符串开头的行
    Shell > cat /etc/services | sed -n '/^netbios/p'
    netbios-ns      137/tcp                         # NETBIOS Name Service
    netbios-ns      137/udp
    netbios-dgm     138/tcp                         # NETBIOS Datagram Service
    netbios-dgm     138/udp
    netbios-ssn     139/tcp                         # NETBIOS session service
    netbios-ssn     139/udp
    

    提示

    众所周知,shell 中的双引号和单引号扮演着不同的角色。双引号中的 $`\ 具有特殊含义。建议在使用 sed 命令时,更多地使用单引号。

    • 打印第 23 行到第 26 行的文本
    Shell > cat -n /etc/services | sed -n '23,26p'
    23  tcpmux          1/tcp                           # TCP port service multiplexer
    24  tcpmux          1/udp                           # TCP port service multiplexer
    25  rje             5/tcp                           # Remote Job Entry
    26  rje             5/udp                           # Remote Job Entry
    
    • 打印奇数行
    Shell > cat -n /etc/services | sed -n '1~2p'
    1  # /etc/services:
    3  #
    5  # IANA services version: last updated 2016-07-08
    7  # Note that it is presently the policy of IANA to assign a single well-known
    9  # even if the protocol doesn't support UDP operations.
    11  # are included, only the more common ones.
    13  # The latest IANA port assignments can be gotten from
    15  # The Well Known Ports are those from 0 through 1023.
    17  # The Dynamic and/or Private Ports are those from 49152 through 65535
    19  # Each line describes one service, and is of the form:
    ...
    
    • 打印第 10 行到最后一行
    Shell > cat -n /etc/services | sed -n '10,$p'
    10  # Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports
    11  # are included, only the more common ones.
    12  #
    13  # The latest IANA port assignments can be gotten from
    14  #       http://www.iana.org/assignments/port-numbers
    15  # The Well Known Ports are those from 0 through 1023.
    16  # The Registered Ports are those from 1024 through 49151
    17  # The Dynamic and/or Private Ports are those from 49152 through 65535
    ...
    
    • 第 10 行到最后一行不打印
    Shell > cat -n /etc/services | sed -n '10,$!p'
    1  # /etc/services:
    2  # $Id: services,v 1.49 2017/08/18 12:43:23 ovasik Exp $
    3  #
    4  # Network services, Internet style
    5  # IANA services version: last updated 2016-07-08
    6  #
    7  # Note that it is presently the policy of IANA to assign a single well-known
    8  # port number for both TCP and UDP; hence, most entries here have two entries
    9  # even if the protocol doesn't support UDP operations.
    
    • 打印匹配字符串的行号和内容
    Shell > sed -n -e '/netbios/=' -e '/netbios/p' /etc/services
    123
    netbios-ns      137/tcp                         # NETBIOS Name Service
    124
    netbios-ns      137/udp
    125
    netbios-dgm     138/tcp                         # NETBIOS Datagram Service
    126
    netbios-dgm     138/udp
    127
    netbios-ssn     139/tcp                         # NETBIOS session service
    128
    netbios-ssn     139/udp
    
    • 匹配字符串范围并打印它

    使用逗号分隔字符串范围

    Shell > cat  /etc/services | sed -n '/^netbios/,/^imap/p'
    netbios-ns      137/tcp                         # NETBIOS Name Service
    netbios-ns      137/udp
    netbios-dgm     138/tcp                         # NETBIOS Datagram Service
    netbios-dgm     138/udp
    netbios-ssn     139/tcp                         # NETBIOS session service
    netbios-ssn     139/udp
    imap            143/tcp         imap2           # Interim Mail Access Proto v2
    

    信息

    范围的开始:匹配字符串所在的行,只匹配第一个出现的字符串。范围的结束:匹配字符串所在的行,只匹配第一个出现的字符串。

    Shell > grep -n ^netbios /etc/services
    123:netbios-ns      137/tcp                         # NETBIOS Name Service
    124:netbios-ns      137/udp
    125:netbios-dgm     138/tcp                         # NETBIOS Datagram Service
    126:netbios-dgm     138/udp
    127:netbios-ssn     139/tcp                         # NETBIOS session service
    128:netbios-ssn     139/udp
    
    Shell > grep -n ^imap /etc/services
    129:imap            143/tcp         imap2           # Interim Mail Access Proto v2
    130:imap            143/udp         imap2
    168:imap3           220/tcp                         # Interactive Mail Access
    169:imap3           220/udp                         # Protocol v3
    260:imaps           993/tcp                         # IMAP over SSL
    261:imaps           993/udp                         # IMAP over SSL
    

    换句话说,上面打印的内容是第 123 行到第 129 行。

    • 打印包含字符串所在的行以及之后的行。
    Shell > cat /etc/services | sed -n '/^netbios/,$p'
    
    • 在 Bash 脚本中使用变量。
    Shell > vim test1.sh
    #!/bin/bash
    a=10
    
    sed -n ''${a}',$!p' /etc/services
    # or
    sed -n "${a},\$!p" /etc/services
    
    • 正则表达式

    仅匹配 “三位数字” + “/udp”。

    Shell > cat /etc/services | sed -r -n '/[^0-9]([1-9]{3}\/udp)/p'
    sunrpc          111/udp         portmapper rpcbind      # RPC 4.0 portmapper UDP
    auth            113/udp         authentication tap ident
    sftp            115/udp
    uucp-path       117/udp
    nntp            119/udp         readnews untp   # USENET News Transfer Protocol
    ntp             123/udp                         # Network Time Protocol
    netbios-ns      137/udp
    netbios-dgm     138/udp
    netbios-ssn     139/udp
    ...
    
  2. 匹配并删除 (d)。

    它类似于打印,只是操作命令被替换为 d,并且不需要 -n 选项。

    • 删除所有匹配 udp 字符串的行,删除所有注释行,以及删除所有空行。
    Shell > sed -e '/udp/d' -e '/^#/d' -e '/^$/d' /etc/services
    tcpmux          1/tcp                           # TCP port service multiplexer
    rje             5/tcp                           # Remote Job Entry
    echo            7/tcp
    discard         9/tcp           sink null
    systat          11/tcp          users
    daytime         13/tcp
    qotd            17/tcp          quote
    chargen         19/tcp          ttytst source
    ftp-data        20/tcp
    ftp             21/tcp
    ssh             22/tcp                          # The Secure Shell (SSH) Protocol
    telnet          23/tcp
    ...
    
    • 删除连续的文本行。
    Shell > cat -n /etc/services | sed '10,$d'
    1  # /etc/services:
    2  # $Id: services,v 1.49 2017/08/18 12:43:23 ovasik Exp $
    3  #
    4  # Network services, Internet style
    5  # IANA services version: last updated 2016-07-08
    6  #
    7  # Note that it is presently the policy of IANA to assign a single well-known
    8  # port number for both TCP and UDP; hence, most entries here have two entries
    9  # even if the protocol doesn't support UDP operations.
    
    • 正则表达式
    Shell > cat  /etc/services | sed -r '/(tcp)|(udp)|(^#)|(^$)/d'
    http            80/sctp                         # HyperText Transfer Protocol
    bgp             179/sctp
    https           443/sctp                        # http protocol over TLS/SSL
    h323hostcall    1720/sctp                       # H.323 Call Control
    nfs             2049/sctp       nfsd shilp      # Network File System
    rtmp            1/ddp                           # Routing Table Maintenance Protocol
    nbp             2/ddp                           # Name Binding Protocol
    echo            4/ddp                           # AppleTalk Echo Protocol
    zip             6/ddp                           # Zone Information Protocol
    discard         9/sctp                  # Discard
    discard         9/dccp                  # Discard SC:DISC
    ...
    
  3. 替换字符串 (s///g)。

    语法语法描述
    sed 's/string/replace/g' FILENAMEs: 代表文件内容的所有行。您也可以指定行范围,例如:sed '20,200s/netbios/TMP/g' /etc/services
    g (全局):如果没有 g,则表示当同一行上出现多个匹配的字符串时,只替换第一个匹配的字符串。
    /: 分隔符样式。您也可以指定其他样式,例如:sed '20,200s?netbios?TMP?g' /etc/services

    提示

    Bash 脚本中的示例

    Shell > vim /root/sedReplace.sh
    #!/bin/bash
    a="SELINUX=enforcing"
    b="SELINUX=disabled"
    
    sed -i 's/'${a}'/'${b}'/g' /etc/selinux/config
    # or
    sed -i "s/${a}/${b}/g" /etc/selinux/config
    
    • 替换并打印
    Shell > sed -n '44,45s/ssh/SSH/gp' /etc/services
    SSH             22/tcp
    SSH             22/udp
    
    • 使用 “&” 符号引用字符串
    Shell > sed -n '44,45s/ssh/&-SSH/gp' /etc/services
    ssh-SSH             22/tcp
    ssh-SSH             22/udp
    
    • 使用字符串定位一行或多行,并替换指定行范围内的指定字符串。
    Shell > grep ssh /etc/services -n
    44:ssh             22/tcp                          # The Secure Shell (SSH) Protocol
    45:ssh             22/udp                          # The Secure Shell (SSH) Protocol
    551:x11-ssh-offset  6010/tcp                        # SSH X11 forwarding offset
    593:ssh             22/sctp                 # SSH
    1351:sshell          614/tcp                 # SSLshell
    1352:sshell          614/udp                 #       SSLshell
    1607:netconf-ssh     830/tcp                 # NETCONF over SSH
    1608:netconf-ssh     830/udp                 # NETCONF over SSH
    7178:sdo-ssh         3897/tcp                # Simple Distributed Objects over SSH
    7179:sdo-ssh         3897/udp                # Simple Distributed Objects over SSH
    7791:netconf-ch-ssh  4334/tcp                # NETCONF Call Home (SSH)
    8473:snmpssh         5161/tcp                # SNMP over SSH Transport Model
    8474:snmpssh-trap    5162/tcp                # SNMP Notification over SSH Transport Model
    9126:tl1-ssh         6252/tcp                # TL1 over SSH
    9127:tl1-ssh         6252/udp                # TL1 over SSH
    10796:ssh-mgmt        17235/tcp               # SSH Tectia Manager
    10797:ssh-mgmt        17235/udp               # SSH Tectia Manager
    
    Shell > sed '/ssh/s/tcp/TCP/gp' -n  /etc/services
    ssh             22/TCP                          # The Secure Shell (SSH) Protocol
    x11-ssh-offset  6010/TCP                        # SSH X11 forwarding offset
    sshell          614/TCP                 # SSLshell
    netconf-ssh     830/TCP                 # NETCONF over SSH
    sdo-ssh         3897/TCP                # Simple Distributed Objects over SSH
    netconf-ch-ssh  4334/TCP                # NETCONF Call Home (SSH)
    snmpssh         5161/TCP                # SNMP over SSH Transport Model
    snmpssh-trap    5162/TCP                # SNMP Notification over SSH Transport Model
    tl1-ssh         6252/TCP                # TL1 over SSH
    ssh-mgmt        17235/TCP               # SSH Tectia Manager
    
    • 连续行的字符串替换。
    Shell > sed '10,30s/tcp/TCP/g' /etc/services
    
    • 多个匹配和替换。
    Shell > cat /etc/services | sed 's/netbios/test1/g ; s/^#//d ; s/dhcp/&t2/g'
    
    • 正则表达式的分组替换。

    在正则表达式中,"()" 是一个分组。\1 代表引用组 1,\2 代表引用组 2,依此类推。

    Shell > cat /etc/services
    ...
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    Shell > cat /etc/services | sed -r 's/([0-9]*\/tcp)/\1\tCONTENT1/g ; s/([0-9]*\/udp)/\1\tADD2/g'
    ...
    axio-disc       35100/tcp       CONTENT1               # Axiomatic discovery protocol
    axio-disc       35100/udp       ADD2               # Axiomatic discovery protocol
    pmwebapi        44323/tcp       CONTENT1               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp       ADD2               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp       CONTENT1               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp       CONTENT1               # Capture handwritten signatures
    

    \t: 即制表符。

    • 将所有注释行替换为空格。
    Shell > cat /etc/services | sed -r 's/(^#.*)//g'
    ...
    chargen         19/udp          ttytst source
    ftp-data        20/tcp
    ftp-data        20/udp
    
    ftp             21/tcp
    ftp             21/udp          fsp fspd
    ssh             22/tcp                          # The Secure Shell (SSH) Protocol
    ssh             22/udp                          # The Secure Shell (SSH) Protocol
    ...
    
    • 将单词中的一个小写字母替换为大写字母。
    Shell > echo -e "hello,world\nPOSIX" | sed -r 's/(.*)w/\1W/g'
    hello,World
    POSIX
    
    • 字符串位置交换。
    Shell > cat /etc/services
    ...
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    

    我们可以将此文件分为五个部分。

    cloudcheck-ping    45514       /     udp        # ASSIA CloudCheck WiFi Management keepalive
     ↓                   ↓         ↓      ↓               ↓
    (.*)           (\<[0-9]+\>)   \/   (tcp|udp)         (.*)
     ↓                   ↓                ↓               ↓ 
     \1                 \2               \3              \4
    
    Shell > cat /etc/services | sed -r 's/(.*)(\<[0-9]+\>)\/(tcp|udp)(.*)/\1\3\/\2\4/g'
    ...
    edi_service     udp/34567               # dhanalakshmi.org EDI Service
    axio-disc       tcp/35100               # Axiomatic discovery protocol
    axio-disc       udp/35100               # Axiomatic discovery protocol
    pmwebapi        tcp/44323               # Performance Co-Pilot client HTTP API
    cloudcheck-ping udp/45514               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      tcp/45514               # ASSIA CloudCheck WiFi Management System
    spremotetablet  tcp/46998               # Capture handwritten signatures
    
    • 删除任何空白字符。
    Shell > echo -e "abcd\t1 2 3 4\tWorld"
    abcd    1 2 3 4 World
    Shell > echo -e "abcd\t1 2 3 4\tWorld" | sed -r 's/(\s)*//g'
    abcd1234World
    
  4. 使用 -e 选项执行多次。

    以下示例

    Shell > tail -n 10 /etc/services
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    Shell > tail -n 10 /etc/services | sed  -e '1,3d' -e '/cloud/s/ping/PING/g'
    # or
    Shell > tail -n 10 /etc/services | sed  '1,3d ; /cloud/s/ping/PING/g'      
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-PING 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
  5. 在特定行之上或之下添加内容 (ia)。

    • 在指定行号之上添加两行内容。
    Shell > tail -n 10 /etc/services > /root/test.txt
    Shell > cat /root/test.txt
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    Shell > cat /root/test.txt | sed '3i 123\
    abc'
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    123
    abc
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    • 在指定行号之下添加三行内容。
    Shell > cat /root/test.txt | sed '5a 123\
    comment yes\
    tcp or udp'
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    123
    comment yes
    tcp or udp
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    • 根据字符串匹配特定行,并在其之上添加 2 行内容。
    Shell > cat /root/test.txt | sed '/tcp/iTCP\
    UDP'
    TCP
    UDP
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    TCP
    UDP
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    TCP
    UDP
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    TCP
    UDP
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    TCP
    UDP
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    TCP
    UDP
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
  6. 替换行 (c)。

    • 根据字符串定位一行或多行,并替换这些文本行。
    Shell > cat /root/test.txt | sed '/ser/c\TMP1 \
    TMP2'
    TMP1
    TMP2
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    TMP1
    TMP2
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    • 单行替换。
    Shell > cat /root/test.txt | sed '7c REPLACE'
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    REPLACE
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    • 替换连续的文本行。
    Shell > cat /root/test.txt | sed '2,$c REPLACE1 \
    replace2'
    aigairserver    21221/tcp               # Services for Air Server
    REPLACE1
    replace2
    
    • 替换偶数行。
    Shell > cat /root/test.txt | sed '2~2c replace'
    aigairserver    21221/tcp               # Services for Air Server
    replace
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    replace
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    replace
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    replace
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    replace
    
  7. 读取文件内容,并将内容追加到匹配行的下方 (r)。

    Shell > cat /root/app.txt
    append1
    POSIX
    UNIX
    
    Shell > cat /root/test.txt | sed '/ping/r /root/app.txt'
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    append1
    POSIX
    UNIX
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
  8. 将匹配行写入其他文件 (w)。

    Shell > cat /root/test.txt | sed '/axio/w /root/storage.txt'
    
    Shell > cat /root/storage.txt
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    
  9. 将输入的下一行读取/追加到 "模式空间" (nN)。

    • 打印匹配行的下一行。
    Shell > cat /root/test.txt
    aigairserver    21221/tcp               # Services for Air Server
    ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    edi_service     34567/udp               # dhanalakshmi.org EDI Service
    axio-disc       35100/tcp               # Axiomatic discovery protocol
    axio-disc       35100/udp               # Axiomatic discovery protocol
    pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    spremotetablet  46998/tcp               # Capture handwritten signatures
    
    Shell > cat /root/test.txt | sed '/ping/{n;p}' -n
    cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    

    提示

    多个 sed 操作命令可能会互相影响,您可以使用 "{ }" 来减少这种影响。

    • 打印偶数文本行。

    首先,读取第一行,因为存在 n 命令;第二行将被打印出来,依此类推。

    Shell > cat -n /root/test.txt | sed -n '{n;p}'
    # or
    Shell > cat -n /root/test.txt | sed -n '2~2p'
    2  ka-kdp          31016/udp               # Kollective Agent Kollective Delivery
    4  edi_service     34567/udp               # dhanalakshmi.org EDI Service
    6  axio-disc       35100/udp               # Axiomatic discovery protocol
    8  cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
    10  spremotetablet  46998/tcp               # Capture handwritten signatures
    
    • 打印奇数文本行。
    Shell > cat -n /root/test.txt | sed -n '{p;n}'
    # or
    Shell > cat -n /root/test.txt | sed -n '1~2p'
    # or
    Shell > cat -n /root/test.txt | sed 'n;d'
    1  aigairserver    21221/tcp               # Services for Air Server
    3  ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    5  axio-disc       35100/tcp               # Axiomatic discovery protocol
    7  pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
    9  cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    
    • 打印 3n 行。
    Shell > cat -n /root/test.txt | sed -n '{n;n;p}'
    # or
    Shell > cat -n /root/test.txt | sed -n '3~3p'
    3  ka-sddp         31016/tcp               # Kollective Agent Secure Distributed Delivery
    6  axio-disc       35100/udp               # Axiomatic discovery protocol
    9  cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
    
    • N

    读取第一行,并在遇到 N 命令后追加一行。在本例中,"模式空间" 为 "1\n2"。最后,执行 q 命令退出。

    Shell > seq 1 10 | sed 'N;q'
    1
    2
    

    由于第 9 行之后没有额外的行,因此输出如下所示。

    Shell > seq 1 9 | sed -n 'N;p'
    1
    2
    3
    4
    5
    6
    7
    8
    

    当读取最后一行时,N 命令不会执行,输出如下所示。

    Shell > seq 1 9 | sed -n '$!N;p'
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    将两行合并为一行。将 "模式空间" 中的 "\n" 替换为空白字符。

    Shell > seq 1 6 | sed 'N;{s/\n//g}'
    12
    34
    56
    
  10. 忽略大小写 (I)。

    man 1 sed 中似乎没有关于忽略大小写的信息。

    Shell > echo -e "abc\nAbc" | sed -n 's/a/X/Igp'
    Xbc
    XBC
    
    Shell > cat /etc/services | sed '/OEM/Ip' -n
    oem-agent       3872/tcp                # OEM Agent
    oem-agent       3872/udp                # OEM Agent
    oemcacao-jmxmp  11172/tcp               # OEM cacao JMX-remoting access point
    oemcacao-rmi    11174/tcp               # OEM cacao rmi registry access point
    oemcacao-websvc 11175/tcp               # OEM cacao web service access point
    
    Shell > cat /etc/services | sed -r '/(TCP)|(UDP)/Id'
    
    Shell > cat /etc/services | sed -r '/(TCP)|(UDP)/Ic TMP'
    
  11. 获取文件中行的总数。

    Shell > cat /etc/services | sed -n '$='
    # or
    Shell > cat /etc/services | wc -l
    
    11473
    

作者:li tianci