流编辑器sed

sed编辑器定义

用于处理文本文件中的数据流。它是一种非交互式的编辑器,可以从标准输入(stdin)或文件中读取输入,然后将文本进行转换、替换、删除、添加等操作,最后将处理后的文本输出到标准输出(stdout)或文件中。它的名字来源于“流编辑器(stream editor)”。

sed编辑器特点

与传统的文本编辑器(如vi和emacs)不同,sed对文件进行的修改是非常快速和高效的,因为它不需要打开文件并读取整个文件内容,而是按行处理文件,只处理必要的部分。此外,sed支持正则表达式,可以在文本文件中进行高级搜索和替换操作。

sed编辑器的工作流程

  1. 一次从输入中读取一行数据
  2. 根据所提供的编辑器命令匹配数据
  3. 按照命令修改流中的数据
  4. 将新的数据输出到STDOUT

在执行过程中,sed编辑器使用的是基于行的处理方式,即每次处理一行数据。而指令则是根据正则表达式来匹配和处理数据的。通过指令的组合使用,可以实现很多文本处理和编辑的功能,比如替换、删除、插入等操作。

sed编辑器基础

sed命令格式

sed options 'command' inputfile

其中,options是可选项,command是sed命令,inputfile是要处理的文件名。如果不指定inputfile,sed将从标准输入读取数据。

基本用法

sed 's/oldstring/newstring/' inputfile

其中,s表示替换操作,oldstring表示要被替换的字符串,newstring表示替换后的字符串,inputfile表示要处理的文件名。此命令将替换文件中的第一个匹配项。

  • 创建文本文件inputfile,填入以下原始数据:

    # Sample Data
    
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@example.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com
  • 根据上述用法将文本中的example替换成test:

    # [操作] 将 example 替换为 test (仅每行第一个)sed "s/example/test/" inputfile
    # Sample Data
    
    Name: John Smith
    Age: 30
    Email: john.smith@test.com
    
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@test.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@test.com
  • 如果要替换所有匹配项,则需要使用g选项,将原始数据中第7行的Jay Jay替换成Jone Jone:

    # [操作] 将 Jay 全局替换为 Jone (使用 g 标记)sed "s/Jay/Jone/g" inputfile
    # Sample Data
    
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    
    Name: Jone Jone
    Age: 25
    Email: Jone.Jone@example.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com

作业1:通过sed命令修改/etc/ssh/sshd_config文件中的Port 22,将端口号改为2222,将命令的输出截图。
扩展:结合正则表达式隐藏手机号的中间四位。

sed -r 's/(1[0-9]{2})[0-9]{4}([0-9]{4})/\1​**​​**​\2/' test.txt

常见选项

  • n:取消默认输出,使用p(print)命令完成输出。

    # [操作] 取消默认输出 (-n),仅打印 (p) 发生替换的行sed -n "s/Jay/Jone/pg" inputfile
    Name: Jone Jone
    Email: Jone.Jone@example.com
  • e:允许多个 sed 命令被执行。

    # [操作] 执行多条指令:替换姓名且替换域名sed -e 's/Jay/Jone/g' -e 's/example/test/' inputfile
    # Sample Data
    
    Name: John Smith
    Age: 30
    Email: john.smith@test.com
    
    Name: Jone Jone
    Age: 25
    Email: Jone.Jone@test.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@test.com
  • f:指定 sed 命令文件。

    sed -f commands.sed inputfile

    commands.sed文件内容:

    s/Jay/Jone/g
    s/example/test/
  • i:直接修改文件,而不是输出到终端。

  • rE:使用扩展正则表达式。

常见命令

  • s:替换字符

  • d:删除命令,用于删除文件中的指定行或指定模式。

    # [删除] 匹配 "Sample" 的行sed "/Sample/d" inputfile
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@example.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com
    
    # [删除] 第 1 到 2 行sed "1,2d" inputfile
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@example.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com
    
    # [删除] 空行 (匹配开头即结尾的行)sed "/^$/d" inputfile
    # Sample Data
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@example.com
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com

其他命令

  • a:添加命令,用于在文件中的指定行后面添加新的内容。

    # 在匹配模式所在行的下一行添加新的内容
    sed '/pattern/a new line' file.txt
    
    # 在指定行号的下一行添加新的内容
    sed '3a new line' file.txt
  • i:插入命令,用于在文件中的指定行前面插入新的内容。

    # 在匹配模式所在行的上一行插入新的内容
    sed '/pattern/i new line' file.txt
    
    # 在指定行号的上一行插入新的内容
    sed '3i new line' file.txt
    
    # 在文件中插入新的文本行:
    sed '1i\New Text' file.txt
  • c:替换命令,用于将指定行替换为新的内容。

    # 将匹配模式所在行替换为新的内容
    sed '/pattern/c new line' file.txt
    
    # 将指定行号替换为新的内容
    sed '3c new line' file.txt

sed正则表达式用法

  1. 删除文件中的空行:

    # [删除] 仅保留非空行sed "/^$/d" inputfile
    # Sample Data
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@example.com
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com

    使用正则表达式匹配空行(以行首和行尾之间没有任何字符的行),然后使用 d 命令删除这些空行。

  2. 删除文件中的注释行:

    # [删除] 以 # 开头的注释行sed "/^#/d" inputfile
    Name: John Smith
    Age: 30
    Email: john.smith@example.com
    
    Name: Jay Jay
    Age: 25
    Email: Jay.Jay@example.com
    
    Name: Michael Johnson
    Age: 35
    Email: michael.johnson@example.com

    使用正则表达式匹配以 #开头的行,然后使用 d命令删除这些行。

  3. 按照指定格式输出文件内容:

    sed 's/\(.*\)/<p>\1<\/p>/' inputfile
  4. 指定行前添加#号:

    sed -r '1,5s/(.*)/#\1/' inputfile
  5. 将文本文件中的每一行都替换为该行的第一个单词:

    sed 's/\([a-zA-Z]*\).*/\1/' inputfile
  6. 提取文本文件中的URL:

    sed -nE 's#.*(https?://[^ ]*).*#\1#p' test.txt

vim中的sed用法

  1. 替换文件中的指定字符串

    在Vim中,可以使用:%s/old/new/g命令来替换文件中的指定字符串,其中“%”表示对整个文件进行操作,s表示替换,/用于分隔替换前、替换后的内容,g表示全局替换。

  2. 删除文件中的指定行

    在Vim中,可以使用:g/pattern/d命令来删除文件中包含指定字符串的行,其中g表示全局匹配,pattern表示要匹配的字符串,d表示删除操作。

  3. 在文件中插入指定字符串

    在Vim中,可以使用:1,$s/^/string/命令在文件的每一行前插入指定字符串,其中1,$表示对整个文件进行操作,^表示行首,string表示要插入的字符串。

作业2:完成本页所有sed命令的用法练习,执行history命令,上传结果。