参数
1 | sed [options] 'command' file(s) |
g 表示行内全面替换。 global 全局
p 表示打印行。 P 打印模板第一行
r 读文件
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法) -i :直接修改读取的文件内容,而不是输出到终端
w 表示把行写入一个文件。
x 表示互换模板块中的文本和缓冲区中的文本。
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
\1 子串匹配标记
& 已匹配字符串标记元字符集
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
- 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
(..) 匹配子串,保存匹配的字符,如s/(love)able/\1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/&/,love这成love。
< 匹配单词的开始,如:/\ 匹配单词的结束,如/love>/匹配包含以love结尾的单词的行。
x{m} 重复字符x,m次,如:/0{5}/匹配包含5个0的行。
x{m,} 重复字符x,至少m次,如:/0{5,}/匹配至少有5个0的行。
x{m,n} 重复字符x,至少m次,不多于n次,如:/0{5,10}/匹配5~10个0的行。
批量替换
把目录下所有格式文件内容进行批量替换
1 | sed -n "s#/pics/${src#$dest#g"p `grep /pics/${src -rl --include=\*.{yaml,md} $path` |
扫描path路径对应格式的文件,把src替换成dest,
sed
-n p 结合打印改变内容,不执行变更
grep
-r 表示查找当前目录以及所有子目录
-l 表示仅列出符合条件的文件名
–include=”*.[ch]” 表示仅查找.c、.h文件
上面不适用大多数情况,推荐下面
–include=*.{yaml,md}
样本1 test.txt (cat -n 显示行号)
1 | 111111111 |
**a\ ** 追加
在当前行下面插入文本。 append 追加
N;2a 指定第二行后追加append
1 | cs@debian:~/~$ sed -i 'N;2a这是a' test.txt |
/匹配/ 不确定行数 a\ 反斜杠可以不要 a
1 | cs@debian:~/~$ sed -i "/这是a/a\匹配追加" test.txt |
**i\ ** 插入
在当前行上面插入文本。 insert 插入
N;2i 指定第二行前插入insert ‘N;2i\这是i’ (\省略)
1 | cs@debian:~/~$ sed -i 'N;2i这是i' test.txt |
/匹配/ 不确定行数
1 | cs@debian:~/~$ sed -i "/这是i/i\匹配插入" test.txt |
匹配多个—》 批量插入
1 | cs@debian:~/~$ sed -i "/这是/i\匹配多个" test.txt |
c\ 把选定的行改为新的文本。
d 删除
删除选择的行。
确定行数
1 | cs@debian:~/~$ sed '2,5d' test.txt |
#2-5行删除
‘2d’ 第2行
‘10,$d’ 10到最后一行
匹配删除 删除匹配下一行 d删除 p打印 #加 -i 直接修改
1 | sed '/这是i/d' test.txt |
样本2
1 | cs@debian:~/~$ cat -n test.txt |
n N p
1 | cs@debian:~/~$ sed '/这是i/{n;d;p}' test.txt |
n匹配下一行
N匹配当前行和下一行
n命令–>移动到匹配行的下一行 {n;操作;}
1 | $ sed -i '/^ZOOKEEPER_PREFIX/{n;s#$#JAVA_HOME=/opt/jdk/jdk-11.0.12#;}' ./zkEnv.sh |
ZOOKEEPER_PREFIX=”${ZOOBINDIR}/..”
JAVA_HOME=/opt/jdk/jdk-11.0.12
#check to see if the conf dir is given as an optional argument
上一行 (提供多的特征匹配)
1 | sed -n '/^if.*JAVA_HOME/i\JAVA_HOME=/opt/jdk/jdk-11.0.12' ./zkEnv.sh |
JAVA_HOME=/opt/jdk/jdk-11.0.12
if [[ -n “$JAVA_HOME” ]] && [[ -x “$JAVA_HOME/bin/java” ]]; then
JAVA=”$JAVA_HOME/bin/java”
elif type -p java; then
N 将下一行读入并附加到当前行后面放到当前空间模式
最后一行结束
1 | cs@debian:~/~$ echo -e "11111\n2222222\n3333" | sed 'N;p' |
P模式空间第一行 N再次执行就到了3 ,隔行
1 | cs@debian:~/~$ echo -e "11111\n2222222\n3333\n44\n55\n6" | sed 'N;P' |
/etc/hosts ip
1 | cs@debian:~$ cat /etc/hosts |
1 | cs@debian:/ip$ ip=node02 |
properties
1 | zookeeper.connect=localhost:2181 |
nginx code
2xx 2[0-9]{2}
4xx 4[0-9]{2}
5xx 5[0-9]{2}
1 | ❯ cat /opt/proxy/nginx/logs/k8s-ssl-access.log | sed -n 's/.*][[:space:]]\(2[0-9]\{2\}\)[[:space:]]\"[GET|POST].*/\1/'p | tail -1 |
192.168.122.1 - 192.168.122.16:443 - [17/Oct/2023:22:14:49 +0800] 200 “GET /api/v1/namespace HTTP/1.1” https://dashboard.ui.k8s.cn/" 4508
192.168.122.1 - 192.168.122.16:443 - [17/Oct/2023:22:12:47 +0800] 200 “POST /api/v1/token/refresh HTTP/1.1” https://dashboard.ui.k8s.cn/" 6573
192.168.122.1 - 192.168.122.16:443 - [17/Oct/2023:22:05:33 +0800] 499 “GET /api/v1/namespace HTTP/1.1” https://dashboard.ui.k8s.cn/" 4508
1 | cat ./access.log | sed 's/\(.*"\) \([2|3|4|5][0-9][0-9]\) \(.*\)/\2/g' | sort | uniq -c | sort -nr |
cat ./access.log | sed ‘s/(.*”) ([2|3|4|5][0-9]{2}) (.*)/\2/g’ | sort | uniq -c | sort -nr
log_format main ‘$remote_addr - $remote_user [$time_local] “$request” $status $body_bytes_sent “$http_referer” “$http_user_agent” “$http_x_forwarded_for”‘;
eg:
192.168.122.1 - - [30/Jun/2024:16:39:50 +0800] “GET /favicon.ico HTTP/1.1” 404 561 “http://192.168.122.1/" “Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36”
sed
:使用sed
匹配模式,即HTTP状态码 。sort
:对状态码进行排序,以便uniq
命令可以统计重复项。uniq -c
:计算每个状态码的出现次数。sort -nr
:以数值方式逆序排序结果。
D
删除模板块的第一行。
s 替换
s/指定字符/替换字符/
relative/directory/ 改为/etc/supervisor.conf.d/
1 | cs@debian:~/~$ sed -n 's/relative\/directory\//\/etc\/supervisor.conf.d\//'p /etc/supervisord.conf |
-n选项和p命令一起使用表示只打印发生替换的行
防火墙关闭
1 | cat /etc/selinux/config | grep ^SELINUX= | sed 's/^SELINUX=.*/SELINUX=disabled/' |
替换整行
1 | cs@debian:~/~$ sed -i '2s/^.*$/xxxxx/' file |
截取
1 | cs@debian:~/~$ echo "tinkle-app-style-0.0.1-SNAPSHOT.jar" | sed 's/\([a-z]-*\)-[0-9].*/\1/' |
匹配模式
() \1~91 | cs@debian:~/~$ echo "abcdef-shea-df" | sed 's/\(.*\)-\(.*\)-\(.*\)/\2/g' |
1 | cs@debian:~$ echo "etch-master.sh" | sed 's/\(.*\)-\(.*\)\.\(.*\)/\2/g' |
1 | cs@debian:~$ systemctl status flanneld.service |
测试匹配模式style=”color: rgb(40, 40, 40);”>[](/pics/11b91ca9f-7cc1-428c-9d06-12e3fe3d7ddf.jpg
1 | ❯ cat 'other/data-structure/binary-tree.md' | sed 's/.*\(\/pics\/[^\/]*\.jpg\).*/\1/g' |
标记跳转
删除前一行 (:a ;ta) a标记,ta执行成功在跳转,类似循环
1 | cs@debian:~/~$ sed -e :a -e '$!N;s/.*\n\(.*是.*\)/\1/;ta' -e 'P;D' test.txt |
前置 s/正则/\1/ $最后一行 !不进行
1 | cs@debian:~/~$ sed -e '$!N;s/.*\n\(.*是i\)/\1/' -e 'p;d' test.txt |
test
1 | 3d5f |
替换Proxy 标签中间部分
1 | sed '/<P/{:a;N;/<\//!ba;s/>[^<].*</>\n替换你们\n</}' test |
注释
join.yaml
1 | #kind: JoinConfiguration |
添加
1 | sed -n '/debian/s/^/#/'p ./join.yaml |
# name: debian #节点名,master要能解析
1 | sed -n 's/debian/#&/'p ./join.yaml |
name: #debian #节点名,master要能解析
1 | cs@debian:~$ cat /etc/fstab | grep swap | sed '/swap/s/^/#/' |
1 | sed -i '/匹配字符串/,+4 s/^/#/' 文件名 #匹配行和下面4行 |
+4表示匹配行和下面4行,一共5行注释
删除
1 | #去掉所有行注释 |
name: debian #节点名,master要能解析
1 | sed 's/^#.*\(en_US.UTF-8\)/\1/' test |
1 | #去注释行 |
1 | sed -i '/匹配字符串/,+4 s/^#*//' 文件名 |
乱码
unknown directive
1 | root@racknerd-070082:~# cat -n -v /usr/local/openresty/nginx/conf/nginx.conf | grep 88 |
cat -v #显示输出不打印M-等一些特殊字符
sed ‘s/\xc2\xa0/ /g’ -i 文件路径 #把”M-BM-“ 替换成空格