sed命令学习笔记
canhui87
canhui87
数据分析
想用Shell灵活处理文本文件,则必须学习sed、awk命令。sed命令功能强大,但选项繁多,脚本可读性较差(一堆斜杆的组合),很多不常用的功能(如模式空间),等想起要用都得再查一下书。所以把常用的命令记录下来,可供自己快速查阅。
注意:本篇是本人的个人学习笔记,很多内容是为了自己工作方便查阅,可读性一般,后续还有awk命令的学习笔记。想系统学习sed命令的,建议阅读以下书籍。
主要参考:
《Linux命令行与shell脚本编程大全(第3版)》
《sed与awk(第二版)》
1 sed常用命令
sed -n '/root/p' mylog.txt :输出符合规则的行
sed '/root/d' mylog.txt :删除
sed -n 's/root/my/p' mylog.txt:替换并输出
sed 's/root/my/g' mylog.txt :全局替换,默认每行只替换第一个
sed 's/root/my&/' mylog.txt :&引用匹配模式
sed -e 's/root/my/' -e 's/2015/2016/' mylog.txt:执行多个命令
sed -i 's/|/\,/g' *.txt :将所有文件|替换为逗号
sed -i 's/^/|/g' mylog.txt :开头添加竖线
sed -i 's/$/|/g' mylog.txt :末尾添加竖线
sed -i '1d' aug_unlimit_output.csv :删除第一行
sed -i "s/\r//g" test.txt :删除回车符
2 sed运行模式
sed运行模式:流编辑命令,每次读取一行数据,保存到缓存区,根据命令匹配数据,处理数据后输出,删除缓存
命令组成:sed [选项] 动作 [文件]
2.1 选项
e 执行脚本,可用于处理多个命令
-f 执行脚本文件
-n 只输出符合规则的行,默认会输出源文件每一行,再输出匹配行
-i 写回原文件,替换、删除
-r 延伸正则语法,默认是普通正则语法
-l 输出文件名
#-e 多个命令
sed -e 's/brown/gree/' -e 's/dog/cat/' mylog.txt
sed -e 's/brown/gree/; s/dog/cat/' mylog.txt
sed -ne 's/brown/gree/; s/dog/cat/p' mylog.txt
sed -e '2{s/brown/gree/
s/dog/cat/}' mylog.txt #跨行命令组合
2.2 动作
动作:寻址|文本过滤/动作/查找/替换/标记
s:替换
p:打印
q:退出
d、D:删除
i:插入到前一行
a:添加到下一行
c:替代行
y:映射
n、N:下一行
2.3 替换标记 s/查找/替换/标记
无标记:默认替换第一处
数字:替换指定第几处
g:替换所有
p:打印,一般与-n选项结合
w:输出匹配结果到新文件
r:读取文件
sed 's/brown/gree/gw newlog.txt' mylog.txt
2.4 特殊字符
反斜杠:\
sed 's/\,/|/' mylog.txt #逗号替换成竖线
sed 's!,!|!' mylog.txt
2.5 寻址
#行寻址
sed '2s/dog/cat/' mylog.txt #第2行
sed '1,3s/dog/cat/' mylog.txt #第1-3行
sed '2,$s/dog/cat/' mylog.txt #第2行开始
#模式寻址,文本过滤 /过滤/s/查找/替换/
sed '/dog1/s/dog/cat/' mylog.txt #只对有dog1的行做替换
sed '2,3{/dog/s/dog/cat/}' mylog.txt #行寻址+模式寻址
sed '/dog/{2,3s/dog/cat/}' mylog.txt #模式寻址+行寻址
2.6 删除 可以结合寻址+文本过滤模式
sed 'd' mylog.txt #删除所有行
sed '1d' mylog.txt #删除首行
sed '2,$d' mylog.txt
sed '/dog1/d' mylog.txt #删除包含dog1的行
sed '2,${/dog/d}' mylog.txt
sed '/dog/{2d}' mylog.txt
sed '/^$/d' mylog.txt #删除空行
2.7 插入
echo 'Test line 1' | sed 'i\Test line 2' #插入前边
echo 'Test line 1' | sed 'a\Test line 2' #后边添加
sed '1i\new line 1' mylog.txt #寻址插入,第一行插入
sed '$a\new line 1' mylog.txt #最后一行插入
2.8 修改 修改整行内容
sed '2c\change line 2' mylog.txt #寻址
sed '/dog2/c\change line 2' mylog.txt #文本过滤
2.9 映射 替换对应位置字符
sed 'y/123/abc/' mylog.txt
2.10 打印
sed -n '/dog1/p' mylog.txt
sed -n '2,3p' mylog.txt
sed -n '{/dog1/p ; s/dog1/cat1/p}' mylog.txt #显示修改前和修改后
brown1 fox lazy dog1
brown1 fox lazy cat1
sed '=' mylog.txt #打印行号
sed '=' mylog.txt | sed 'N;s/\n/ /' #同cat -n mylog.txt
3 sed高级命令
3.1多行命令
#n 查找到匹配行后转换到下一行
sed '/dog1/{n;d}' mylog.txt #删除指定行的下一行
sed '/dog1/{N;d}' mylog.txt #删除两行
sed '/dog1/{N;D}' mylog.txt #删除第一行
#N 查找到匹配行后,将下一行添加到当前行
sed '/dog1/{N;s/\n//}' mylog.txt #合并2行,删除换行符
3.2 排除命令
sed -n '/dog1/!p' mylog.txt
sed -n '$!N ; s/lazy dog/lazy cat/' mylog.txt #最后一行不合并
3.3 分支标签 [地址]b [标签]
sed '{2,3b ; s/dog/cat/}' mylog.txt #b后不带标签,直接跳到结尾
sed '{/A/b lab1; s/dog/cat/ ; :lab1 s/dog/pig/}' mylog.txt # if A: s/dog/pig/ else:s/dog/cat/
3.4 测试 [地址]t [标签]
sed '{s/dog1/cat/; t ; s/dog/pig/}' mylog.txt #未匹配则跳转到标签
3.5 循环
#每次替换一个逗号
echo 'This,is,a,test' | sed -n '{:start ; s/,/ /1p ; /,/b start}' # while /,/: s/,/ /
echo 'This,is,a,test' | sed -n '{:start ; s/,/ /1p ; t start}'
This is,a,test
This is a,test
This is a test
3.6 模式引用 & \数字
echo 'The cat sleeps in his hat.' | sed 's/.at/"&"/g'
The "cat" sleeps in his "hat".
echo 'The cat sleeps in his hat.' | sed 's/\(.at\) sleeps/big \1/g'
The big cat in his hat.
4 空间
4.1 模式空间、保持空间
模式空间:处理每一行的临时缓冲区,处理完每一行,打印缓冲区,清空缓存
保持空间:特殊缓冲区,初始化为一行空行,不会主动打印、自动清空,需要使用特定命令
d:删除模式空间
p:打印模式空间
h、H:保存,复制、追加模式空间到保存空间
g、G:获取,复制、追加保存空间到模式空间
x:交换模式空间和保存空间内容
sed -n '{1!G ; h ; $p}' mylog.txt #倒序打印 同tac mylog.txt
sed '1!G ; h ; $!d' mylog.txt #倒序打印
sed 'G' mylog.txt #每行后边添加空行
sed '$!G' mylog.txt #每行间添加空行,最后一行不添加
sed 'x;p;x' mylog.txt #每行前边添加空行
sed '1!{x;p;x}' mylog.txt #每行前边添加空行,第一行不添加
4.2 替换换行符
sed ':loop ; N ; $!b loop ; s/\n/--/g' mylog.txt #合并所有行
4.3 合并非"结尾的换行
echo '"59659781","汕头市11号","11号","7"
333863381,"汕头市1
号","1
号","7"
333863382,"汕头市3号","3号","7"' > loupan.csv
sed ':loop ; /"$/!N ; /"$/!b loop ; s/\n/--/g' loupan.csv
4.4 替换换行符Python版
#用sed空间模式循环处理每一行,逻辑复杂,而且在不同的shell版本中,处理效果还不一样,所以像这种逻辑复杂的处理最好还是用python处理
#用python pandas读取csv,替换换行符
import pandas as pd
df=pd.read_csv("add.csv",header=None)
for i in range(df.shape[1]):
if df.dtypes[i]=='object':
df[i]=df[i].str.replace('\r|\n','')
df.to_csv('pd.csv',index=None,header=None)
5 ksh版本sed命令
Linux默认shell版本是bash,AIX默认shell版本是ksh,ksh版的sed命令比bash版的功能差很多。
#没i命令,修改只能重定向到新文件
sed -e 's/$/|/g' test.txt > test1.txt
#回车换行等特殊字符 必须用echo命令
sed -e "s/`echo \\\r`//g" test.txt > test1.txt