Shell之sed

sed是什么

Linux sed 命令是利用脚本来处理文本文件。 可依照脚本的指令来处理、编辑文本文件。主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

sed命令详解

语法
sed [-hnV][-e <script>][-f<script文件>][文本文件]
sed [-nefr] [动作]

参数

-e<script>或--expression=<script> 以选项中指定的script来处理输入的文本文件。

-f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;

-h或--help 显示帮助。

-n或--quiet或--silent 仅显示script处理后的结果。

动作

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)

c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行

d :删除

i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);

p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行

s :取代,可以直接进行取代的工作。通常这个 s 的动作可以搭配正则表达式!例如 1,20s/old/new/g

高级子命令

高级子命令比较少,但是比较复杂,平时用的也会相对少些,却也很重要,有的内容处理不用高级子命令是完成不了的。

n:读入下一行到模式空间,例:'4{n;d}' 删除第5行。

N:追加下一行到模式空间,再把当前行和下一行同时应用后面的命令。

P:输出多行模式空间的第一部分,直到第一个嵌入的换行符位置。在执行完脚本的最后一个命令之后,模式空间的内容自动输出。P命令经常出现在N命令之后和D命令之前。

D:删除模式空间中第一个换行符的内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用与模式空间剩余的内容。这3个命令能建立一个输入、输出循环,用来维护两行模式空间,但是一次只输出一行。
例子1:
sed 'N;$!P;D' a.txt

#说明:删除文件倒数第二行

例子2:
sed 'N;! P ; !P;!P;!D;$d' a.txt

例子

bash 复制代码
#在 testfile 文件的第四行后添加一行
sed -e 4a\newLine testfile 
#将 testfile 的内容列出并且列印行号,同时,请将第 2~5 行删除!
nl testfile | sed '2,5d'
#要删除第 3 到最后一行:
nl testfile | sed '3,$d' 
#第二行后(即加在第三行) 加上test 字样
nl testfile | sed 'test'
#第二行前 加上test 字样
nl testfile | sed '2i drink tea' 
#要增加两行以上,在第二行后面加入两行字,例如 test0 与 test1?
nl testfile | sed '2a test0\
test1'
#取代2到5行的内容
nl testfile | sed '2,5c No 2-5 number'
#列出 testfile 文件内的第 5-7 行
nl testfile | sed -n '5,7p'
#搜索 testfile 有 oo 关键字的行
nl testfile | sed -n '/oo/p'
#删除 testfile 所有包含 oo 的行,其他行输出
nl testfile | sed  '/oo/d'
#数据的搜寻并执行命令
#搜索 testfile,找到 oo 对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把 oo 替换为 kk,再输出这行。最后的 q 是退出。
nl testfile | sed -n '/oo/{s/oo/kk/;p;q}'  

#数据的查找与替换
#除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的查找与替换。sed 的查找与替换的与 vi 命令类似,语法格式如下:
sed 's/要被取代的字串/新的字串/g'
#将 testfile 文件中每行第一次出现的 oo 用字符串 kk 替换,然后将该文件内容输出到标准输出:
sed -e 's/oo/kk/' testfile
#g 标识符表示全局查找替换,使 sed 对文件中所有符合的字符串都被替换,修改后内容会到标准输出,不会修改原文件:
sed -e 's/oo/kk/g' testfile
#选项 i 使 sed 修改文件:
sed -i 's/oo/kk/g' testfile
#批量操作当前目录下以 test 开头的文件:
sed -i 's/oo/kk/g' ./test*

#样本 inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
#将 IP 前面的部分予以删除:
/sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'
#将 IP 后面的部分予以删除:
/sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'

#多点编辑
一条 sed 命令,删除 testfile 第三行到末尾的数据,并把 HELLO 替换为 test 
nl testfile | sed -e '3,$d' -e 's/HELLO/test/'

#直接修改文件内容
#sed 将 regular_express.txt 内每一行结尾若为.则换成!
sed -i 's/\.$/\!/g' regular_express.txt
#利用 sed 直接在 regular_express.txt 最后一行加入 # This is a test:
sed -i '$a # This is a test' regular_express.txt
#把hello换成A保存到file.txt,同时会以file.txt.bak文件备份原来未修改文件内容,以确保原始文件内容安全性,防止错误操作而无法恢复原来内容。
sed --i.bak 's/hello/A/' file.txt
echo "hello world" | sed -r 's/(hello)|(world)/A/g'
#将第2-4行中hello字符串替换为A,其它行如果有hello也不会被替换。
sed --n '2,4s/hello/A/' message
#从第2行开始,再接着往下数4行,也就是2-6行,这些行会把hello字符替换为A。
sed --n '2,+4s/hello/A/' message
#第4行开始,到第6行。解释6的由来,"4,~3"表示从4行开始到下一个3的倍数,这里从4开始算,那就是6了,当然9就不是了,因为是要求3的第一个超过前边数字4的倍数
sed --n '4,~3s/hello/A/' message
#从第4行开始,每隔3行就把hello替换为A。比如从4行开始,7行,10行等依次+3行。这个比较常用,比如3替换为2的时候,也就是每隔2行的步调,可以实现奇数和偶数行的操作。
sed --n '4~3s/hello/A/' message
#!符号表示取反,该命令是将除了第1行,其它行hello替换为A,上述定址方式也可以使用!符号
sed -n '1!s/hello/A/' message
#将匹配到nihao的行执行删除操作。
sed -n '/nihao/d' message
#删除空行
sed -n '/^$/d' message
#说明:匹配以TS开头的行到TE开头的行之间的行,把匹配到的这些行删除。
sed -n '/TS/,/TE/d' message
#匹配从第1行到TS开头的行,把匹配的行删除
sed -n '1,/^TS/d' message
#将从TS开头的行到TE开头的行之间范围的行内容中CN替换为China,并且把Beijing替换为BJ,类似于多命令之间用分号的那种方式,不过这样定址代码只写了一遍,相当于执行了一条子命令。
/TS/,/TE/{
s/CN/China/
s/Beijing/BJ/
}
sed -n `2,3s{/cn/china/;/a/b/}` message
#将message文件中1-2行的下边分别添加3行,3行内容分别是A、B、C,这里使用了\n,插入多行内容都可以按照这种方式来实现。
sed `1,2a A\nB\nC` message


cat message
hello 123 world
#将message每行包含的第一个hello的字符串替换为HELLO,这是最基本的用法。
sed 's/hello/HELLO/' message
#用了扩展正则表达式,需要加-r选项。结果:A
sed -r 's/[a-z]+ [0-9]+ [a-z]+/A/' message
#结果:hello 123 world
sed -r 's/([a-z]+)( [0-9]+ )([a-z]+)/\1\2\3/' message
#\1表示正则第一个分组结果,\2表示正则匹配第二个分组结果,\3表示正则匹配第三个分组结果。结果:world 123 hello
sed -r 's/([a-z]+)( [0-9]+ )([a-z]+)/\3\2\1/' message
# &表示正则表达式匹配的整个结果集。结果:hello 123 world
sed -r 's/([a-z]+)( [0-9]+ )([a-z]+)/&/' message
#在匹配结果前后分别加了111、222。结果:111hello 123 world222
sed -r 's/([a-z]+)( [0-9]+ )([a-z]+)/111&222/' message
#在message文件中每行的首尾分别加上111、222。
sed -r 's/.*/111&222/' message
#把message文件中每行的所有i字符替换为A,默认不加g标记时只替换每行的第一个字符。
sed 's/i/A/g' message
#把message文件中每行的第2个i字符替换为A。
sed 's/i/A/2' message
#加-p标记会把被替换的行打印出来,再加上-n选项会关闭模式空间打印模式,因此该命令的效果就是只显示被替换修改的行。
sed -n 's/i/A/p' message
#把message文件中内容的每行第一个字符i替换为A,然后把修改内容另存为b.txt文件。
sed -n 's/i/A/w b.txt' message
#把message文件中每一行的第一个i或I字符替换为A字符,也即是忽略大小写。
sed -n 's/i/A/i' message

#删除文件每行的第二个字符。
sed -r 's/(.*)(.)$/\1/'
#删除文件每行的最后一个字符。
sed -r 's/(.*)(.)$/\1/'
#删除文件每行的倒数第2个单词。
sed -r 's/(.)([a-Z]+)([a-Z]+)([a-Z]+)([a-Z]+)([^a-Z]$)/\1\2\4\5/' /etc/passwd
#交换每行的第一个字符和第二个字符。
sed -r 's/(.)(.)(.*)/\2\1\3/' /etc/passwd
#交换每行的第一个单词和最后一个单词。
sed -r 's/([a-Z]+)([a-Z]+)(.*)([a-Z]+)([a-Z]+)([^a-Z]*$)/\5\2\3\4\1\6/' /etc/passwd
#删除一个文件中所有的数字。
sed 's/[0-9]//g' /etc/passwd
#用制表符替换文件中出现的所有空格。
sed -r 's/ +/\t/g' /etc/passwd
#把所有大写字母用括号()括起来。
sed -r 's/([A-Z])/(\1)/g' /etc/passwd
#打印每行3次。
sed 'p;p' /etc/passwd
#隔行删除
sed '0~2{=;d}' /etc/passwd
#把文件从第22行到第33行复制到56行后面。
sed '22h;23,33H;56G' /etc/passwd
#把文件从第22行到第33行移动到第56行后面。
sed '22{h;d};23,33{H;d};56g' /etc/passwd
#只显示每行的第一个单词。
sed -r 's/([a-Z]+)([^a-Z]+)(.*)/\1/' /etc/passwd
#打印每行的第一个单词和第三个单词。
sed -r 's/([a-Z]+)([a-Z]+)([a-Z]+)([a-Z]+)([a-Z]+)([^a-Z]+)(.*)/\1\t\5/' /etc/passwd
#将格式为mm/yy/dd的日期格式换成 mm;yy;dd
date `+%m/%y/%d' | sed 's///;/g'
相关推荐
Yana.nice1 小时前
openssl将证书从p7b转换为crt格式
java·linux
AI逐月1 小时前
tmux 常用命令总结:从入门到稳定使用的一篇实战博客
linux·服务器·ssh·php
小白跃升坊2 小时前
基于1Panel的AI运维
linux·运维·人工智能·ai大模型·教学·ai agent
跃渊Yuey2 小时前
【Linux】线程同步与互斥
linux·笔记
舰长1152 小时前
linux 实现文件共享的实现方式比较
linux·服务器·网络
zmjjdank1ng2 小时前
Linux 输出重定向
linux·运维
路由侠内网穿透.2 小时前
本地部署智能家居集成解决方案 ESPHome 并实现外部访问( Linux 版本)
linux·运维·服务器·网络协议·智能家居
VekiSon3 小时前
Linux内核驱动——基础概念与开发环境搭建
linux·运维·服务器·c语言·arm开发
zl_dfq3 小时前
Linux 之 【进程信号】(signal、kill、raise、abort、alarm、Core Dump核心转储机制)
linux
Ankie Wan3 小时前
cgroup(Control Group)是 Linux 内核提供的一种机制,用来“控制、限制、隔离、统计”进程对系统资源的使用。
linux·容器·cgroup·lxc