文本处理
sed

一、sed 是什么

sed 是英文 Steam EDitor 的缩写,即流编辑器。它的主要功能是对文本进行编辑和转换,可以从文件或标准输入读取内容,按照指定规则对文本进行替换、删除、插入、追加等操作,最后将处理结果输出到屏幕或指定文件中 。在实际应用里,sed 常用于批量处理文本文件,比如修改配置文件、替换文本中的某些字符等。而且,sed 能灵活搭配正则表达式,这大大提高了文本处理的效率和精度 。

二、sed 操作配置文件的常用命令

(一)备份配置文件

在对配置文件进行任何修改前,务必先备份,以防操作失误导致数据丢失。以/etc/sysctl.conf配置文件为例,使用cp命令进行备份:

cp /etc/sysctl.conf /etc/sysctl.conf.bak

此命令将/etc/sysctl.conf文件复制为/etc/sysctl.conf.bak,备份文件在后续若出现问题时可用于恢复原配置。本教程已.bak文件为操作对象,以免配置文件损坏。

(二)查看配置文件特定行

  1. 打印指定行:使用sed -n 'Np'命令打印配置文件的第N行。比如查看/etc/ssh/sshd_config配置文件的第5行,命令如下:
sed -n '5p' /etc/ssh/sshd_config.bak

-n参数用于抑制默认输出,仅打印匹配的行,这里即第5行内容。

  1. 打印行范围:若要打印配置文件的第M行到第N行,可使用sed -n 'M,Np'命令。例如,打印/etc/ssh/sshd_config.bak配置文件的第10行到第15行:
sed -n '10,15p' /etc/ssh/sshd_config.bak

(三)添加内容到配置文件

  1. 在指定行后添加:使用sed -i 'Na text'在配置文件第N行后添加文本 “text”。假设要在/etc/sysctl.conf.bak文件的第20行后添加一行配置net.ipv4.ip_forward = 1,命令如下:
cp /etc/sysctl.conf /etc/sysctl.conf.bak
sed -i '20a net.ipv4.ip_forward = 1' /etc/sysctl.conf.bak

a表示追加(append),-i参数使sed直接修改原文件。

  1. 在指定行前添加:利用sed -i 'Ni text'在配置文件第N行前添加文本 “text”。如在/etc/hosts.bak文件的第3行前添加192.168.1.100 myserver,命令为:
cp /etc/hosts /etc/hosts.bak
sed -i '3i 192.168.1.100  myserver' /etc/hosts.bak

i表示插入(insert)。

(四)删除配置文件中的行

使用sed -i 'Nd'删除配置文件的第N行。若要删除/etc/resolv.conf.bak文件中可能存在的无效 DNS 服务器配置行(假设是第4行),命令如下:

cp /etc/resolv.conf /etc/resolv.conf.bak
sed -i '4d' /etc/resolv.conf.bak

(五)替换配置文件中的内容

  1. 全局替换:sed -i 's/old_text/new_text/g'用于在配置文件中全局替换文本。例如,在/etc/httpd/conf/httpd.conf.bak文件中,将所有的AllowOverride None替换为AllowOverride All,命令为:
sudo apt install apache2
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak
sed -i 's/AllowOverride None/AllowOverride All/g' /etc/httpd/conf/httpd.conf.bak

g表示全局(global)替换,即对整行中所有符合条件的字符串进行替换。

  1. 基于行号替换:若只想替换配置文件中某一行的部分内容,可结合行号使用。如在/etc/sysctl.conf.bak文件的第30行中,将kernel.printk = 4 4 1 7替换为kernel.printk = 5 4 1 7,命令如下:
sed -i '30s/kernel.printk = 4 4 1 7/kernel.printk = 5 4 1 7/' /etc/sysctl.conf.bak

(六)使用正则表达式进行复杂替换

sed 支持正则表达式,这在处理复杂的配置文件修改时非常有用。比如在/etc/nginx/nginx.conf.bak文件中,要注释掉所有以server_name开头的行(即在行首添加#),可以使用如下命令:

apt install nginx
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sed -i '/^server_name/s/^/#/' /etc/nginx/nginx.conf.bak

/^server_name/是正则表达式,用于匹配以server_name开头的行,s/^/#/表示将匹配到的行的行首替换为#,实现注释该行的目的。

三、sed 的语法

(一)查看帮助和版本信息

查看帮助信息:使用sed --help命令可以查看 sed 指令的详细帮助信息,了解其各种参数和使用方法 。

查看版本信息:sed --version命令用于查看当前安装的 sed 的版本信息 。

(二)常用操作语法

添加字符串:

sed '[line number]a [string]' [filename]:在文件的第line number行后添加特定字符串string

例如sed '3a This is a new line' test.txt,会在test.txt文件的第三行后添加 This is a new line

sed '[line number]i [string]' [filename]:在文件的第line number行前添加特定字符串string

例如sed '2i Before this line' test.txt,会在test.txt文件的第二行前添加 Before this line

删除行:sed '[line number]d' [filename]用于删除文件中第line number行的内容 。

sed '5d' test.txt,会删除test.txt文件的第五行 。

打印行:sed -n '[line number]p' [filename]用于打印文件中第line number行的内容 。

例如sed -n '4p' test.txt,会打印出test.txt文件的第四行内容 。使用-n参数是为了抑制默认的输出,只打印符合条件的行 。

替换行内容:sed '[line number]c [string]' [filename]将文件中第line number行的内容替换为string

例如sed '6c New content' test.txt,会把test.txt文件的第六行内容替换为 New content

四、sed 和 vim 的选择

在大多数文本处理场景下,sed 能完成的任务,vim 也可以实现。但它们有着不同的适用场景 。

vim:适合交互式操作,用户可以直接对文件进行处理,并即时看到结果。在操作过程中,如果出现错误,还可通过u指令撤回上一步操作,方便进行小范围的文本编辑和修改 。

sed:更适合用于自动化脚本中的批处理操作。它能够同时处理多个文件,并且可以避免人为的误操作,在需要对大量文件进行统一的文本处理时,sed 的优势就体现得尤为明显 。