sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并无 改变,sed只是对缓冲区中原始文件的副本进行编辑,并非编辑原始的文件。除非你使用重定向存储输出或者使用使用sed编辑命令中的w选项。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操做。html
SED是一个非交互式文本编辑器,它可对文本文件和标准输入进行编辑,标准输入能够来自键盘输入、文本重定向、字符串、变量,甚至来自于管道的文本,与VIM编辑器相似,它一次处理一行内容,Sed能够编辑一个或多个文件,简化对文件的反复操做、编写转换程序等。linux
在处理文本时把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),紧接着用SED命令处理缓冲区中的内容,处理完成后把缓冲区的内容输出至屏幕或者写入文件。正则表达式
逐行处理直到文件末尾,然而若是打印在屏幕上,实质文件内容并无改变,除非你使用重定向存储输出或者写入文件。其语法参数格式为:shell
sed [-Options] [‘Commands’] filename;bash |
x #x为指定行号;编辑器
x,y #指定从x到y的行号范围;工具
/pattern/ #查询包含模式的行;ui
/pattern/pattern/ #查询包含两个模式的行;this
/pattern/,x #从与pattern的匹配行到x号行之间的行;spa
x,/pattern/ #从x号行到与pattern的匹配行之间的行;
x,y! #查询不包括x和y行号的行;
r #从另外一个文件中读文件;
w #将文本写入到一个文件;
y #变换字符;
q #第一个模式匹配完成后退出;
l #显示与八进制ASCII码等价的控制字符;
元字符集
^: 匹配一行的开始
$: 匹配一行的结束
.: 匹配某个字符
[abc]: 匹配指定范围字符
sed : Stream EDitor 行编辑器 (全屏编辑器 : vi)
sed : 模式空间 默认不编辑原文件,仅对模式空间中的数据作处理 : 然后,处理结束后,将模式空间打印至屏幕: sed 'AddressCommand' file ...
Address(地址) 指定方法: 一、StartLin(起始行),EndLine(结束行) 好比 :1,100 $ :最后一行 二、/RegExp/(正则表达式指定的模式) /^root/ 三、/pattern1/,/pattern2/ 第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的全部行 四、LineNumber 五、StartLine(起始行), +N 从StartLine开始,向后的N行:
sed [options] '{command}' [filename] sed [options] -f scriptfile [filename]
经常使用选项 | 选项说明 |
---|---|
sed -n | 抑制自动输出;静默模式,再也不默认显示模式空间中的内容 |
sed -e SCRIPT -e SCRIPT | 添加脚本 ;能够同时执行多个脚本 |
sed -f /PATH/TO/SED_SCRIPT | 添加脚本文件 |
sed -f /PATH/TO/SED_SCRIPT file
| sed -i | 编辑文件内容;直接修改源文件 | | sed -i.bak | 修改文件同时建立.bak备份文件 | | sed -r | 使用扩展的正则表达式;将指定的文件的内容添加至符合条件的行处 |
经常使用命令参数 | 参数说明 |
---|---|
a \“string” | 在匹配后面添加新的行,内容为“string” |
案例:一、sed '/^\//a \# hello word' /etc/fstab #在/etc/fstab后面,添加hello word。 二、sed '/^\//a \# hello word\n#hello,linux' /etc/fstab #在/etc/fstab后面,添加hello word和hello,Linux。
| d | 删除符合条件的行 | 案例 :一、sed '1,2d' /etc/fstab #删除/etc/fstab 中的第1,2行 二、sed '1,$-1d' /etc/fstab #删除/etc/fstab 中的第1到到数第二行 三、sed '3,$d' /etc/fstab #删除/etc/fstab 中的31到最后1行 | i \string | 在匹配前面添加新行,内容为string | \n:能够用于换行 | s | 查找替换,默认只替换每行中第一行被模式匹配到的字符 | 加修饰符 g:全局替换 i:忽略字符大小写 案例 :一、 sed 's/oot/OOT' /etc/fstab #在/etc/fstab中的oot替换成OOT 二、 sed 's/^//#/' /etc/fstab #在/etc/fstab中的行首的/替换成# 三、 sed 's///#/' /etc/fstab #在/etc/fstab中的所有的/替换成# | p | 打印 / 显示符合条件的行| 案例 : sed '/^//p' /etc/fstab #显示/etc/fstab下,以/开头的行 | y FILE| 转换 |
| w FILE| 将地址指定范围内的行另存至指定的文件中 | | h H | 拷贝/添加模式空间到存放空间 | | g G | 拷贝/添加存放空间到模式空间 |
sed -i.bak '/^\s*#/d;/^$/d' <filename>
详细介绍一下上面的脚本:
sed -i.bak
:sed 命令会建立一个以.bak
结尾的备份文件,用来备份原始的文件。/^
:表示行首。\s*
:匹配任何不可见字符,包括空格、制表符、换页符等。#/
:shell 脚本中的注释标记。/^\s*#/
一块儿使用用来查找注释行和带有不可见字符的注释行。d
:用来删除匹配的行。;/^$/d
:;
是表达式的分隔符,后面的表达式跟前面的表达式意思很像,用来删除空白行, "$"匹配输入字符串的结束位置。
a\ 当前行下面插入文本。 i\ 在当前行上面插入文本。 c\ 把选定的行改成新的文本。 d 删除,删除选择的行。 D 删除模板块的第一行。 s 替换指定字符 h 拷贝模板块的内容到内存中的缓冲区。 H 追加模板块的内容到内存中的缓冲区。 g 得到内存缓冲区的内容,并替代当前模板块中的文本。 G 得到内存缓冲区的内容,并追加到当前模板块文本的后面。 l 列表不能打印字符的清单。 n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。 N 追加下一个输入行到模板块后面并在两者间嵌入一个新行,改变当前行号码。
N 追加下一个输入行到模板块后面并在两者间嵌入一个新行,改变当前行号码。
p 打印模板块的行。
P (大写) 打印模板块的第一行
^ 行的开始
$ 行的结尾
. 一个字符
* 0个或多个前一个字符
[] 方括号中的全部字符
{} 重复次数
() 组
/./ 匹配至少有一个字符的行
/../ 匹配至少有两个字符的行
/^#/ 匹配用#开头的行
/^$/ 匹配空行
/}$/ 匹配用}结尾的行(没有空格在后面)
/} *$/ 匹配用}结尾的行(能够有空格在后面)
/[abc]/ 匹配小写的a或b或c
/^<a href="#footnote-abc"><sup>[abc]</sup></a>/ 匹配开头不是小写的a或b或c
一般而言,SED将待处理的行读入模式空间,脚本中的命令逐行进行处理,直到脚本执行完毕,而后该行被输出,模式空间请空;而后重复刚才的动做,文件中的新的一行被读入,直到文件处理完备。
若是用户但愿在某个条件下脚本中的某个命令被执行,或者但愿模式空间获得保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这时可使用SED高级语法来知足用户需求。总的来讲,SED高级命令能够分为三种功能:
N、D、P:处理多行模式空间的问题;
H、h、G、g、x:将模式空间的内容放入存储空间以便接下来的编辑;
:、b、t:在脚本中实现分支与条件结构。
一、在jfedu.txt每行后加入空行,也即每行占永两行空间,每一行后边插入一行空行、两行空行及前三行每行后插入空行:
sed ‘/^$/d;G’ jfedu.txt
sed ‘/^$/d;G;G’ jfedu.txt
sed ‘/^$/d;1,3G;’ jfedu.txt
二、将jfedu.txt偶数行删除及隔两行删除一行:
sed ‘n;d’ jfedu.txt
sed ‘n;n;d’ jfedu.txt
三、在jfedu.txt匹配行前一行、后一行插入空行以及同时在匹配先后插入空行:
sed ‘/jfedu/{x;p;x;}’ jfedu.txt
sed ‘/jfedu/G’ jfedu.txt
sed ‘/jfedu/{x;p;x;G;}’ jfedu.txt
四、在jfedu.txt每行后加入空行,也即每行占永两行空间,每一行后边插入空行:
sed ‘/^$/d;G’ jfedu.txt
五、在jfedu.txt每行后加入空行,也即每行占永两行空间,每一行后边插入空行:
sed ‘/^$/d;G’ jfedu.txt
六、在jfedu.txt每行前加入顺序数字序号、加上制表符\t及.符号:
sed = jfedu.txt| sed ‘N;s/\n/ /’
sed = jfedu.txt| sed ‘N;s/\n/\t/’
sed = jfedu.txt| sed ‘N;s/\n/\./’
七、删除jfedu.txt行前和行尾的任意空格:
sed ‘s/^[ \t]*//;s/[ \t]*$//’ jfedu.txt
八、打印jfedu.txt关键词old与new之间的内容:
sed -n ‘/old/,/new/’p jfedu.txt |
九、打印及删除jfedu.txt最后两行:
sed ‘$!N;$!D’ jfedu.txt sed ‘N;$!P;$!D;$d’ jfedu.txt |
十、合并上下两行,也即两行合并:
sed ‘$!N;s/\n/ /’ jfedu.txt sed ‘N;s/\n/ /’ jfedu.txt |
1. sed -n '5'p /etc/passwd
2. sed -n '1,5'p /etc/passwd
3. sed -n '1,$'p /etc/passwd
4. sed -n '/root/'p /etc/passwd
5. sed -n '/^1/'p /etc/passwd
6. sed -n 'in$'p /etc/passwd
7. sed -n '/r..o/'p /etc/passwd
8. sed -n 'oo*'p /etc/passwd
9. sed -e '1'p -e /111/'p -n /etc/passwd
十、sed -n '+5'p /etc/passwd
十一、sed '2r /etc/issue' /etc/fstab #在/etc/fstab第二行添加etc/issue
十二、sed '$r /etc/issue' /etc/fstab #在/etc/fstab第后面行添加etc/issue
1三、sed '1,2r /etc/issue' /etc/fstab #在/etc/fstab第一,二行添加etc/issue
sed -n '1,3p' #打印出file1文件第一到第三行
sed -e 's/jk$/yz/g' test.txt #修改文本中以jk结尾的替换成
sed ‘s/old/new/g’ jfedu.txt #替换jfedu.txt文本中old为new
sed -n ‘1,3p’ jfedu.txt # 打印jfedu.txt文本第一行至第三行
sed -n ‘1p;$p’ jfedu.txt #打印jfedu.txt文本中第一行与最后一行:
sed ‘1,3d’ jfedu.txt sed ‘/jfedu/,$d’ jfedu.txt #删除jfedu.txt第一行至第三行、删除匹配行至最后一行: |
for i in `seq 1 6`;do sed -i ‘$d’ jfedu.txt ;done sed ‘$d’ jfedu.txt #删除jfedu.txt最后6行及删除最后一行 |
sed ‘$d’ jfedu.txt #删除jfedu.txt最后一行
打印最后一行
[root@localhost ~]# sed -n '$ p' jfedu.net
打印匹配对应字符行
[root@localhost ~]# sed -n '/baidu/ p' jfedu.net
打印从第一行到匹配行
[root@localhost ~]# sed -n '1,/jf/ p' jfedu.net
以匹配条件做为匹配实例
[root@localhost ~]# sed -n '/jfedu/,/jf/ p'
在匹配文本的上一行或者是下一行增长行
[root@localhost ~]# sed '/baidu/ a www.baidu1.com'
在匹配行的下一行增长参数
[root@localhost ~]# sed '/baidu/ i www.baidu1.com'
追加字符
[root@localhost ~]# sed 's/com$/ test &/g' jfedu.net
[root@localhost ~]# sed 's/com$/ & test/g' jfedu.net
修改一下示例文件:
sed -i
's/^www/https:\/\/&/g;s/com$/&\/index.html/;s/net$/&\/
index.html/' jfedu.net
修改示例文件,单独取出域名
#示例awk
[root@localhost ~]# awk -F"/" '{print $3}' jfedu.net
1四、删除/etc/grub.conf文件中行首的空白符 sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf
1五、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5; sed 's@(id:)[0-9](:initdefault:)@\15\2@g' /etc/inittab
1六、删除/etc/inittab文件中空白行; sed '/^$/d' /etc/inittab
1七、删除/etc/inittab文件中开头的#号 sed 's@^@@g' /etc/inittab
1八、删除某文件中之后面的空白字符,但要求#号后面必须有空白字符;
sed -r 'S@^[[!space:]]+#@@g' /etc/inittab
1九、删除某文件中以空白字符后面跟#类的行中的开头的空白字符 # sed -r 's@^[[!space:]]+#@@g' /etc/inittab
20、取出一个文件路径的目录名称; echo "/etc/rc.d/" sed -r 's@^(/.*/)[^/]+/7@\1@g'
2一、传递一个参数(单字符就行)给脚本,如参数为q,Q,quit,或Quit,就退出脚本:不然,就显示用户的参数:
#!/bin/bash
if [ $1 = 'q' ];then echo "Quiting..."
elif [ $1 = 'Q' ];
then echo "Quiting..." exit 2 elif [ $1 = 'quit' ];
then echo "Quiting..." exit 4 else echo $1
fi
2二、统计一共有多少个用户
for I in 'seq 1 $LINES'; do echo "Hello, 'head -n $I /etc/passwd | tail -l | cut -d:-f1'";done 只向默认shell为bash的用户问声好
2三、添加10个用户user1到user10,密码同用户名,但要求只有用户不存在的状况下才能添加。 扩展 : 接受一个参数: add : 添加用户user1..user10 del :删除用户user1..user10 其余:退出
#!/bin/bash
for I in (1..10); do if id user$I &>/dev/null; then echo 'user$I' exists. else useradd user$I echo user$I | passwd --stdin user$I &> /dev/null echo "Add user user$I finished." fi done
#!/bin/bash
for I in (1..10); do if id user$I &>/dev/null; then userdell -r user$I echo 'Delete user$I' fineshed. else echo "user$I not exist." fi done
2四、查找/var目录下属主为root而且属组为mail的全部文件:
find /var -user root -group mial
2五、查找/usr目录下不属于root,bin,或student的文件: find /usr -not -user root -a -not -user bin -a -not -user student find /usr -not ( -user root -o -user bin -o -user student )
2六、查找/etc目录下最近一周内内容修改且不属于root及student用户的文件: find /etc -mtime -7 -not \ ( -user root -o -user student ) find /etc/ -mtime -7 -not -user root -a -not -user student
2七、查找当前系统上没有属主或属组且最近1天内曾被访问过的文件,并将其属主属组均修改成root: find / \( -nouser -o nogroup \) -a -atime -1 -exec chown root:root () ;
2八、查找/etc目录下大于1M的文件,并将其文件写入/tmp/etc.largefiles文件中: find /etc/ -size -1M >> /tmp/etc.largefiles
2九、查找/etc目录下全部用户都没有写权限的文件,显示出其详细信息; find /etc -not -perm /222 -ls
30、查找/etc目录下大于1M的文件,并追加到/tmp/etc.largefiels
find /etc -szie +1M -exec echo {} >> /tmp/etc.largefile ; find /etc -szie +1M xarges echo {} >> /tmp/etc.largefile
3一、命令:a\
在匹配行的后面加入一行文本
示例(4)匹配100的行,后面加入一行"new line"
sed '/100/'a\ "new line" hello.txt
输出内容为:
1 2 3
10 20 30
100 200 300
new line
命令:i\
在匹配行的前面加入一行文本
示例(5)匹配100的行,前面加入一行"new line"
sed '/100/'i\ "new line" hello.txt
输出内容为:
1 2 3
10 20 30
new line
100 200 300
命令:c\
将匹配行替换为目的行
示例(5)匹配100的行,替换为"new line"
sed '/100/'c\ "new line" hello.txt
输出内容为:
1 2 3
10 20 30
new line
命令:d
将匹配行删除
示例(5)删除匹配100的行
sed '/100/'d hello.txt
输出内容为:
1 2 3
10 20 30
命令:s
将匹配行替换
详细命令为:s/pattern-to-find/replacement-pattern/g
pattern-to-find:被替换的串
replacement-pattern:替换成这个串
g:所有替换,默认只替换匹配到的第一个
示例(5)讲100替换为hello
sed 's/100/hello/g' hello.txt
输出内容为:
1 2 3
10 20 30
hello 200 300
匹配以10开头的行,并替换为yes,并输出
sed -n 's/^10/yes/p' hello.txt
输出内容为:
yes 20 30
yes0 200 300
取出文件中行手的行号与冒号
设hello.txt的内容为
1:#!/bin/sh
2:cat hello.txt
3:exit
sed -n -e 's/^[0-9]\{1,\}://g'p hello.txt
输出结果为:
#!/bin/sh
cat hello.txt
exit
3二、
3三、
3四、
3五、
3六、
3七、
3八、
3九、
40、
## 删除 第1行
sed '1'd /etc/passwd
sed '1d' /etc/passwd
## 删除 第1行 和 第3行
sed '1,3'd /etc/passwd
## 删除包含 字符串oot的行
sed '/oot/'d /etc/passwd
## 删除空白行
sed '/^$/d' /etc/passwd
## 删除文件最后一行
sed '$d' /etc/passwd
十二、sed '1,+2d' /etc/fstab #删除第一行和向后的两行
1三、
sed 's/[0-9]//g' /etc/passwd
sed s/[a-zA-Z]//g' /etc/passwd
sed 's#ot#to#g' /etc/passwd
## 行下追加
[root@ansible-master awk]# head -2 text | sed '/^root/a\this is a test line'
root:x:0:0:root:/root:/bin/bash
this is a test line
rootaaaaa:x:10:0:root:/root:/bin/bash
this is a test line
## 指定行下追加
[root@ansible-master awk]# head -3 text | sed '2a\this is a test line'
root:x:0:0:root:/root:/bin/bash
rootaaaaa:x:10:0:root:/root:/bin/bash
this is a test line
## 指定行上追加
[root@ansible-master awk]# head -3 text | sed '2i\this is a test line'
root:x:0:0:root:/root:/bin/bash
this is a test line
rootaaaaa:x:10:0:root:/root:/bin/bash
## 匹配行上追加
[root@ansible-master awk]# head -5 text | sed '/^root/i\this is a test line'
this is a test line
root:x:0:0:root:/root:/bin/bash
this is a test line
rootaaaaa:x:10:0:root:/root:/bin/bash
## 匹配并替换,将第1字段 和 第7字段进行互换
[root@ansible-master awk]# sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/' /etc/passwd
/bin/bash:x:0:0:root:/root:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon
/sbin/nologin:x:3:4:adm:/var/adm:adm
## 在行首添加字符串 aaa
[root@ansible-master awk]# sed -r 's/(.*)/aaa:&/' /etc/passwd
aaa:root:x:0:0:root:/root:/bin/bash
aaa:bin:x:1:1:bin:/bin:/sbin/nologin
aaa:daemon:x:2:2:daemon:/sbin:/sbin/nologin
参考连接 : https://mp.weixin.qq.com/s/P6iB1xw8rFtjbwkSPlouQQ
SHELL——文本处理(三):sed关于 p、d、a、c、i 模式 : https://blog.csdn.net/qq_42036824/article/details/85225654