Hi,阿金 ...

Linux三剑客之sed

发表: 2019-04-20 分类:

Linux之 sed 命令

sed命令主要用来修改文本文件用的,使用命令的方式来快速修改文件.
和vim一样,但是它是使用交互式命令的.
一般和管道命令一起使用.
主要功能: 插入,删除,选中,替换
以之前user.csv文件举例.
文件如下:

由于MacOs的sed和gnu-sed不一样,我们以gnu-sed为准.
mac安装.
brew install gnu-sed
修改sed alias sed=gsed 在.zsh或bash环境改.
或者改软链接.
ln /usr/local/bin/gsed /usr/local/bin/sed

必须前置知识:
标准输入/输出,有时间再细说.
linux有三种标准输入/输出.

名称 文件描述 含义 设备
STDIN 0 标准输入 键盘
STDOUT 1 标准输出 显示器
STDERR 2 标准错误 显示器

STDIN: 标准输入,普通的键盘输入
比如我们收集一个输入当成变量.

1
2
read -p "用户名:" username
echo $username

ps: zsh和bash的语法稍微不同.
zsh环境使用

1
2
read -s "pwd?密码:"
echo $pwd


提示:
zsh用 “变量?提示符代替-p”
-s: 隐藏输入

废话说. 这里的输入就是标准的STDIN

STDOUT:意思是输出到显示器的内容.
echo 输出来的内容就是 标准输出.
我们常见的一个语句.
xxx.sh 2>&1 > /dev/null
这语句表示”所有的错误和输出都重定向到黑洞里面”
解释一下这语句.主要是 2>&1 > /dev/null
2: 表示STDERR,错误消息
1: 表示STDOUT,标准输出
>: 表示重定向,全写应该是 1> 代表标准输出重定向.还有 2>,代表错误重定向.
/dev/null: 表示文件,只是dev/null是一个特殊空文件

关键是 2>&1 > ,全写应该是 2>&1 1> xxx,意思是把2也是STDERR错误输出 重定向到1标准输出,最后标准输出,重定向到 某个文件.
也可 反着写.

2>&1放到最后.

|:管道符,表示 把 前面命令的标准输出当到后面命令的标准输入.
如:

1
2
3
cat user.csv | awk {print}
# 相当于
awk {print} user.csv

了解了标准输入输出和管道符,重定向,开始sed的正题

参数

-e : 在命令行模式下编辑,默认就是-e,可以省略
-i : 写入文件,
-n : 只显示匹配行,不加该参数,默认打印最终结果
-f : 使用外部脚本,相对于-e,太复杂不讲

写入文件

sed 标准输入,只能在内存和标准输出中修改,只有使用 > 重定向 才能写入到文件.
平时我们使用 sed 只在标准输出中修改,一般不直接修改文件,因为直接修改文件有风险.
怎么修改文件呢?
使用 sed -i '备份后缀名' '操作命令' 文件
注:macOS必须填写备份后缀名,但允许为空
例:我们要删除文件的第1行.

1
sed -ie '1d' user.csv

1d 代表删除第1行,后面 “删除” 再细讲.
在使用标准输入时就不能用 -i 参数了.
echo "lalalalal" | sed -ie '1d' 这个就会出错.

意思. 使用 -i 必须带文件.
实际修改文件 使用 -i参数.

标准输入

后面基演示都在标准输入和标准输出.不修改文件本身.

删除行操作

使用 d 命令
按行删除
sed -e '1d' user.csv

解释:
1d: 1为第1行,d代表删除操作符,

1,4: 代表1至4行
$:代表最后一行
例:

正则删除
sed '/正则/d'
删除带关键字”阿木”的行:
sed '/阿木/d' user.csv
删除空白行
sed '/^[\( \)|\s]*$/d' user.csv
注意:sed 的正则很变态,(){}有时需要转义,有时不需要.

增加行

使用ai操作符
a: 在后面追加
i: 在前面添加
格式:
sed -e '/模式/a 内容' 文件

在第1行前加1行内容:
sed -e '1i 内容' user.csv

在最后一行添加1行内容:
sed -e '$a 最后一行' user.csv
注意空文件的情况.文件必须存在且不能为空.
避免空文件空行,一般用>或 ‘>>’ 添加.
echo '' > tmp.txt

查找到正则添加:
sed -e '/阿金/i "# 这就是我"' user.csv

修改内容

修改内容是很常用的功能.
使用s命令
语法:
sed -e 's/正则/替换/模式'

如修改配置文件:把root变成admin

1
sed -i -e 's/username=\(.*\);/username=admin;/' config.ini

打印行

p来打印输出行.
打印奇数行
sed -n -e '1~2p' user.csv
解释: ~表示递增,从1行开始递增,1,1+2,3+2行
偶数行:
sed -n -e '0~2p' user.csv
0,2,2+2行
匹配行的下一行
sed -n -e '2{n;p}' //第2行的下1行,第3行
上一行:
sed -n -e '2{p;n}' //第2行的上1行,第1行

范围打印:
sed -n -e '/开始正则/,/结束正则/'

读取文件

r命令
在匹配行下,读取加载文件内容.
例,在php类中为每个函数里面加载一段代码.

1
sed -e '/function \([A-Za-z0-9_]*\)(\(.*\)){/r log_hook.php' class.php

效果如下.

写入文件

w,把匹配的每一行写入到某个文件,和上面刚好相反.

1
sed -e '/function \([A-Za-z0-9_]*\)(\(.*\)){/w function.php' class.php

跨行匹配

sed默认是按行处理的.有时候有大段文字是跨多行的,就不好处理了.
sed '/开始标准/,/结束标记/'
比如上面截取函数列表.

1
sed -n -e '/function /,/\}/w function.php' class.php

得到这样的结果.

本文作者:阿金

本文链接:http://www.hi-arkin.com/2019/04/20/Linux/sed/

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

扫描二维码,分享此文章