Linux sed 命令是利用脚本来处理文本文件。

sed 可依照脚本的指令来处理、编辑文本文件。

Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

引用自菜鸟教程https://www.runoob.com/linux/linux-comm-sed.html

我们来练习,先新建一个testfile

1
cat testfile内容

image-20230317003806667

以行为单位的新增/删除

然后在第四行后面加一行,使用

1
sed -e 4a\newLine testfile

image-20230317003953620

下面将testfile内容列出并印出行号,同时将第2-5行删除,使用

1
nl testfile | sed '2,5d'

image-20230317004231592

其实可以看出前面的输出作为后面的输入!详见管道符原理。

注意sed后面接的动作必须要用两个单引号引起来。如:

1
nl testfile | sed '2d'

如果要删除第三行到最后一行,就是用

1
nl testfile | sed '3,$d'#也就是说这里$表示末尾的意思!

注意sed的操作没有-i时并不改变原文件!只是在管道中改变并且输出。

如果在第二行后面加上drink tea字样,即

1
nl testfile | sed '2a drink tea'#这样就会加到第二行原来内容的后面!

看运行截图

image-20230317004727367

但是如果加到前面也就是用

1
nl testfile | sed '2i drink tea'#即可

如果要增加两行以上,也就是要出现换行,就用以下写法

1
2
3
nl testfile | sed '2a drink tea or .....\
> drink beer?'
#也就是要结果换行的地方,我们的输入也先\然后回车换行。

看运行结果

image-20230317005038147

以行为单位的替换与显示

将2-5行内容取代成为其他字符

1
nl testfile | sed '2,5c No 2,5 number'

执行显示

image-20230317090405579

然后就是搜寻具体行的内容,与vim里面的类似了

比如搜寻某一关键字

1
nl testfile | sed -n '/oo/p'

这样就会输出所有含有oo的行。

搜寻并且直接删除关键字所在的行可以用如下方法:

1
nl testfile | sed '/oo/d'

如图所示成功删除

image-20230317090821434

数据的搜寻并且执行其他命令

搜索testfile找到oo对应的行,然后把oo替换成kk再输出这一行

1
nl testfile | sed -n '/oo/{s/oo/kk/;p;q}'#最后的q是退出,p表示输出行某一行,s表示替换模式每个命令之间用分号分割

image-20230317091234789

总体来说就是先选中oo然后开始对其执行一系列命令,这里的-n表示显示处理后的结果!

数据的查找与替换,与vim相似

1
sed -e 's/oo/kk/' testfile#注意这里使用了命令-e因为目标不是屏幕上的显示的东西,而是一个文本文件,并没有进入管道。

这个命令只能替换第一个oo。

1
sed -e 's/oo/kk' testfile这个能替换所有oo为kk

当然也可以如图所示来显示

image-20230317093523441

选项-i用来修改文件,选项-e表示以选项中指定的script来处理输入的文本文件。

来看一个题目

先查询ip,然后将ip地址前面部分给予删除

首先

1
ifconfig ens18

如图所示

image-20230317094441367

我们只要ip部分,所以

1
ifconfig ens18 | grep -n 'inet' | sed 's/^.*inet//g' | sed 's/netmask.*$//g'#上面//显然表示替换成空也就相当于删除

image-20230317095033317

可以看到ip确实被我们跳了出来。

复习一下上面涉及到的正则表达式

1
2
3
4
'.'表示匹配除了\n以外任何字符
所以直接连用'.*'因为*表示匹配前面的子式0次或多次。
而^表示从字符起始开始匹配,所以通常用'^.*'当然也有'^.+'
这里+表示匹配前面子式1次或多次。

我们来分析apache_log

首先分析sql注入

1
nl apache_logs | sed -n '/select/p'

查看有没有注入

image-20230317101732141

显然有一个,然后我们再查找

1
nl apache_logs | sed -n '/userid/p'

可以发现几乎全部的语句

image-20230317104750846

下面要生成攻击者的ip地址列表

1
2
nl apache_logs | sed -n '/userid/p' | sed 's/^[^ ]* [^ ]* \([^ ]*\) .*$/\1/g'
#正则表达式中的空格可以匹配多个空格!也可以不匹配空格!

我们也可以只提取ip地址不要前面的编号,

1
sed -n 's/.* \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\) .*userid.*/\1/p' apache_logs

里面的-n 禁止默认输出,只输出匹配到的行。

下面提取时间戳:

1
2
3
sed -n '/userid/s/^[^[]*\(\[[^ ]*\]\).*$/\1/p' apache_logs
sed -n '/userid/s/^[^[]*\(\[[^]]*\]\).*$/\1/p' apache_logs
对比这两行为什么第一行不行,因为第一行代表匹配中括号里面没空格就行,然而里面有空格!十分麻烦。

-p表示打印替换后的行。

在正则表达式中,方括号被用来匹配字符集,所以需要使用反斜杠进行转义,以便匹配实际的方括号字符。

总之,当需要匹配特殊字符时,通常需要使用转义符号。

接下来做ip隐藏

1
nl apache_logs | sed -n '/userid/p' | sed 's/^[^ ]* [^ ]* \([^ ]*\) .*$/192.168.1.1/g'

就可以替换成其他ip。