sed简单学习

SED

sed编辑器基础

sed是用来解析和转换文本的工具,是简洁的程序设计语言。来自贝尔实验室。

sed简介

sed是非交互式的面向数据流的编辑器,提供了交互式文本编辑器的自然扩展功能。有助于编写简单的shell脚本,如:替换文本、删除某行、差入新文本等。

sed特点:

  1. 自动化地编辑一个或多个文件

  2. 简化在多个文件中执行相同操作的任务

  3. 编写转换程序

模式空间

模式空间类似于一个工作区或临时缓冲区。sed操作的不是郑振的文本,而是一个类似快照的东西。sed一次处理一行数据,这就避免了将一个很大的文件读入内存,而产生内存益处或者处理速度过慢的情况。

基本的sed编辑命令

sed从标准数入获取数入并发送输出到标准输出。sed命令的语法有两种:在命令行指定或将sed放入一个文件并将其文件名作为参数:

sed [OPTIONS]... 'COMMAND' [FILE]...

sed [OPTIONS] -f SCRIPTFILE [FILE]...

sed有一些常用的选项:

  • -e:告诉sed将下一个参数解释为sed指令,只有在命令行上给出多个sed指令才需要使用-e选项

  • -f:指定由sed指令组成的脚本名称。如果sed脚本的第一行位"#n",则sed的行为与指定-n选项相同

  • -i:直接修改读取的内容,而不是输出到终端

  • -n:取消默认输出;一般情况下,sed处理后整个文件内容都会输出到终端,但是使用-n后,只由经过sed处理的行才会被显示出来

sed指令由地址和编辑命令组成。如果指令的地址被匹配到,那么编辑命令就被应用到匹配的行。sed的编辑命令由24个,常用的有:追加(a)、更改(c)、删除(d)、插入(i)、替换(s)、打印(l)、打印行号(=)、转换(y)。

追加、更改、插入编辑命令

追加命令将文本放置在当前行之后;更改命令用所指定的文本取代模式空间的内容;插入命令将所提供的文本在模式空间的当前行之前。这些命令中的每个都要求后面跟一个反斜杠用于转义第一个行尾,text必须从下一行开始。要输入多行文本,每个连续的行都必须反斜杠结束,最后一行除外。如果文本中包含了一个字面含义的反斜杠,需要转义。

如:

文本内容:

[root@localhost sed]# cat test.txt 
I like YOU but just LIKE you
​
you should be brave and harry

追加一行内容:

[root@localhost sed]# sed '$a<end of the file>' test.txt 
I like YOU but just LIKE you
​
you should be brave and harry
<end of the file>

$是寻址符号,用于匹配文件的最后一行。提供的文本在前行之后输出,所以输出到了最后一行

更改数据

插入数据:如,给test.txt文件插入一行数据(第一行插入"#!/bin/bash")

[root@localhost sed]# sed 1i\#\!/bin/bash test.txt 
#!/bin/bash
I like YOU but just LIKE you
​
you should be brave and harry

删除编辑命令

删除编辑命令采用一个地址,如果行匹配到该地址,就删除内容。

如:

删除文件中的空行

[root@localhost sed]# sed '/^$/d' test.txt 
I like YOU but just LIKE you
you should be brave and harry

也可以删除指定的行

[root@localhost sed]# sed '1d' test.txt 
​
you should be brave and harry

删除了第一行

甚至删除一个范围内的行

[root@localhost sed]# sed '2,$d' test.txt 
I like YOU but just LIKE you

删除了第二行之后所有的行

替换编辑命令

替换编辑命令算是sed一个特别重要的命令了,具体语法:

[address]s/pattern/replacement/flags

flages是替换命令的修饰标志,有如下几个:

  • n——1~512之间的数字,表示对文本模式pattern中指定模式第n次出现的情况进行替换

  • g——对模式空间所有匹配的进行替换,如果没有g,一般替换第一次出现的匹配

  • p——打印模式空间的内容

  • w file——将模式空间的内容写入到file中

替换命令用于地址匹配的行,如果没有指定地址,就应用于所有的行。

replacement是一个字符串,用来替换与模式匹配的内容。replacement有由几个字符有特殊含义:

  • &——由正则表达式匹配的字符串进行替换

  • \n——匹配第n个字符串,这个字符串时在pattern(模式)中指定的

  • \——用于转义符号&或\

如:

[root@localhost sed]# cat sedsub 
s/I/He/1
[root@localhost sed]# sed -f sedsub test.txt 
He like YOU but just LIKE you
​
you should be brave and harry

打印行号编辑命令

跟在地址后面的等号用来打印被匹配到的行的行号。

如:

[root@localhost sed]# sed = test.txt 
1
I like YOU but just LIKE you
2
​
3
you should be brave and harry

sed命令实例

操作文件test.txt

[root@localhost sed]# cat test.txt 
I like YOU but just LIKE you
​
you should be brave and harry

向文件中添加或插入行

实例1:在文件的指定行之后添加一行内容

如:在test.txt文件第二行添加一行数据

[root@localhost sed]# sed '2a this is a row for test' test.txt
I like YOU but just LIKE you
​
this is a row for test
you should be brave and harry

实例2:在匹配模式的行之后添加一行内容

[root@localhost sed]# sed '/harry/a this is a test for exaple2' test.txt 
I like YOU but just LIKE you
​
you should be brave and harry
this is a test for exaple2

实例3:在文件的最后一行添加多行内容

[root@localhost sed]# sed '$a\
> this is test line 1 \
> this is test line 2' test.txt
I like YOU but just LIKE you
​
you should be brave and harry
this is test line 1 
this is test line 2

实例4:在文件中的指定行前插入数据

在第三行前添加一行数据:

[root@localhost sed]# sed '3i this is a test' test.txt 
I like YOU but just LIKE you
​
this is a test
you should be brave and harry

实例5:在匹配模式的行至前添加一行内容

[root@localhost sed]# sed '/harry/i this is a test' test.txt 
I like YOU but just LIKE you
​
this is a test
you should be brave and harry
[root@localhost sed]# sed '/^$/i this is a test' test.txt 
I like YOU but just LIKE you
this is a test
​
you should be brave and harry

实例6:在文件最后一行至前插入年内容

[root@localhost sed]# sed '$i this is a test' test.txt 
I like YOU but just LIKE you
​
this is a test
you should be brave and harry

更改文件中指定的行

实例1:修改文件第一行

[root@localhost sed]# sed '1c this is a test' test.txt 
this is a test
​
you should be brave and harry

实例2:修改匹配模式的行

[root@localhost sed]# sed '/^$/c this is a test' test.txt 
I like YOU but just LIKE you
this is a test
you should be brave and harry

实例3:更改最后一行

[root@localhost sed]# sed '$c this is a test' test.txt 
I like YOU but just LIKE you
​
this is a test

删除文件中的行

有文件test.txt,同删除测试。

[root@localhost sed]# cat test.txt 
I like YOU but just LIKE you
​
you should be brave and harry
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

实例1:删除文件中指定的行,删除test.txt中的第2行

[root@localhost sed]# sed '2d' test.txt 
I like YOU but just LIKE you
you should be brave and harry
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

实例2:从指定的行开始删除,并每个固定的行数删除一行。从第一行开始删除,每个二行删除一行

[root@localhost sed]# sed '1~2d' test.txt 
​
life was amazing
run from cmd exopse copy add volume maintainer

实例3:删除指定范围的行,删除2-3行数据

[root@localhost sed]# sed '2,3d' test.txt 
I like YOU but just LIKE you
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

实例4:删除指定范围内的行,删除除第二三行外所有的行

[root@localhost sed]# sed '2,3!d' test.txt 
​
you should be brave and harry

实例5:删除文件中最后一行

[root@localhost sed]# sed '$d' test.txt 
I like YOU but just LIKE you
​
you should be brave and harry
life was amazing
1234567890

实例6:删除文件中匹配模式指定的行。删除含有YOU的行

[root@localhost sed]# sed '/YOU/d' test.txt 
​
you should be brave and harry
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

实例7:从匹配模式的行删除到指定的行,匹配到YOU,开始删除到第2行

[root@localhost sed]# sed '/YOU/, 2d' test.txt 
you should be brave and harry
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

实例8:删除文件中匹配指定模式的行以及之后n行数据,删除匹配到YOU,和之后3行的数据

[root@localhost sed]# sed '/YOU/, +3d' test.txt 
1234567890
run from cmd exopse copy add volume maintainer

实例9:删除文件中的空白行

[root@localhost sed]# sed '/^$/d' test.txt 
I like YOU but just LIKE you
you should be brave and harry
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

实例10:删除文件中不匹配指定模式的行,删除匹配不到YOU的所有行

[root@localhost sed]# sed '/YOU/!d' test.txt 
I like YOU but just LIKE you

实例11:删除文件的指定范围内的匹配到匹配模式的行,删除3-5行中匹配到you的行

[root@localhost sed]# sed '3,5{/you/d}' test.txt 
I like YOU but just LIKE you
​
life was amazing
1234567890
run from cmd exopse copy add volume maintainer

替换文件中的内容

使用文件test.txt作为测试文件。

[root@localhost sed]# cat test2.txt 
I like YOU but just LIKE you 1
​
you should be brave and harry you you 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

实例1:替换一行中第一个匹配到的字符串,将每一行匹配到的第一个you替换成he

[root@localhost sed]# sed 's/you/he/' test2.txt 
I like YOU but just LIKE he 1
​
he should be brave and harry you you 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

第三行后面还有两个you,但是不会被匹配到

实例2:替换文件中的匹配指定模式的所有字符串,将每一行匹配到的所有you替换成he

[root@localhost sed]# sed 's/you/he/g' test2.txt 
I like YOU but just LIKE he 1
​
he should be brave and harry he he 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

实例3:替换文件中每行第n个匹配指定模式的字符串,将匹配到的第二个you替换成he

[root@localhost sed]# sed 's/you/he/2' test2.txt 
I like YOU but just LIKE you 1
​
you should be brave and harry he you 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

实例4:将发生字符串替换的行写入指定的文件,并打印只替换的行

[root@localhost sed]# sed -n 's/you/he/gpw output.txt' test2.txt 
I like YOU but just LIKE he 1
he should be brave and harry he he 3
[root@localhost sed]# cat output.txt 
I like YOU but just LIKE he 1
he should be brave and harry he he 3

注意:g是全局,p是打印,w是写入文件,-n是静默模式(不打印到标准输出)

实例5:只替换文件中匹配指定模式的行中的字符串

[root@localhost sed]# sed '3{s/you/he/g}' test2.txt 
I like YOU but just LIKE you 1
​
he should be brave and harry he he 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

实例6:删除每行最后的n个字符。删除每行最后三个字符

[root@localhost sed]# sed 's/...$//g' test2.txt 
I like YOU but just LIKE yo
​
you should be brave and harry you yo
life was amazin
123456789
run from cmd exopse copy add volume maintaine

实例7:删除文件中的注释

[root@localhost sed]# sed 's/^#.*//' test2.txt 
I like YOU but just LIKE you 1
​
you should be brave and harry you you 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

实例8:删除文件中以"#"号开头的注释及空行

[root@localhost sed]# sed '/^#/d;/^$/d' test2.txt 
I like YOU but just LIKE you 1
you should be brave and harry you you 3
life was amazing 4
1234567890 5
run from cmd exopse copy add volume maintainer 6

sed与shell

在sed中使用shell变量

shell中环境变量以"$"开头,而在sed中,符号"​$"用于只是输出文件中的最后一行或行尾(正则表达)。sed不能直接访问SHELL中的变量,所以必须使用双引号来扩展shell变量。

如果想要shell正确解释sed命令中的shell变量,就要将sed指令放在双引号内。如:

[root@localhost sed]# cat input.file 
the name of terminal which you are using is _terminal-type_.
[root@localhost sed]# sed "s/_terminal-type_./$TERM/g" input.file
the name of terminal which you are using is xterm-256color

如果用的是单引号,则$不会被认为是引用:

[root@localhost sed]# sed 's/_terminal-type_./$TERM/g' input.file
the name of terminal which you are using is $TERM

test.txt用于进行测试,文件内容如下:

[root@localhost 14_4]# cat test.txt 
I like YOU but JUST like you
​
狗肉汤就是用狗肉炖成的汤
​
rr wrr source_hash desternation_hash
​
#lc wlc sed nq lblc lblcr

实例1:

移除文件中空白行的shell脚本:removeblanklines.sh

脚本内容:

[root@localhost 14_4]# cat RemoveBlankLines.sh 
#!/bin/bash
​
#移除文件中的空白行
​
#检查传递给脚本的参数,如果没有指定参数,则打印脚本使用方法
if [ -z "$1" ]
then
    echo "Usage: `basename $0` traget-file."
    #退出脚本,退出状态码为1
    exit 1
fi
​
sed -e "/^$/d" "$1"
#其中,-e表示后跟一个编辑命令
# ^$,表示模式匹配空白行
# d指定删除
# 这里只是在模式空间中修改,如果要修改真正文本,加-i选项
exit 0

执行结果:

[root@localhost 14_4]# bash RemoveBlankLines.sh test.txt 
I like YOU but JUST like you
狗肉汤就是用狗肉炖成的汤
rr wrr source_hash desternation_hash
#lc wlc sed nq lblc lblcr

实例2:替换文件中的字符串的脚本:substituteStr.sh

脚本内容:

[root@localhost 14_4]# cat substituteStr.sh 
#!/bin/bash
​
#替换文件中字符串的脚本
​
#检查传递给脚本的参数,如果没有指定参数,则打印脚本使用方法
if [ $# != 3 ]
then
    echo "Usage: `basename $0` old_sting new_string traget-file."
    #退出脚本,退出状态码为1
    exit 1
fi
if [ -f "$3" ]
then
    sed -e "s/$1/$2/g" "$3"
else
    echo "file does not exits."
fi
# 这里只是在模式空间中修改,如果要修改真正文本,加-i选项
exit 0

执行结果:

[root@localhost 14_4]# bash substituteStr.sh 
Usage: substituteStr.sh old_sting new_string traget-file.
​
[root@localhost 14_4]# bash substituteStr.sh "YOU" "you" test.txt 
I like you but JUST like you
​
狗肉汤就是用狗肉炖成的汤
​
rr wrr source_hash desternation_hash
​
#lc wlc sed nq lblc lblcr
​
[root@localhost 14_4]# bash substituteStr.sh YOU you test 
file does not exits.

实例3:检查目录中所有二进制文件的来源的脚本:checkAuthorship.sh

脚本内容:

root@localhost 14_4]# cat checkAuthorship_2.sh 
#!/bin/bash
​
#此脚本用于在指定目录中找含有特定字符串的二进制文件
​
# 检查传入参数是否为空,如果为空,打印使用方法,并退出
if [ $# != 2 ]
then
    echo "Usage:`basename $0` target_dir string."
    exit 1
fi
​
# 检查指定目录是否存在
if [ -d "$1" ]
then    # 如果指定目录存在,则继续
    Dir="$1"
else
    echo "Dir $1 does not exits."
    exit 2
fi
​
fstring=$2
​
for file in `find $Dir -type f -name '*' | sort`
do
    strings -f $file | grep "$fstring" | sed -e "s#$Dir##"
    #cat $file | grep "$fstring" | sed -e "s#$Dir##"
done
​
exit 0

执行结果:

[root@localhost 14_4]# bash checkAuthorship_2.sh    //参数不全
Usage:checkAuthorship_2.sh target_dir string.
​
[root@localhost 14_4]# bash checkAuthorship_2.sh /mnt/test/shell/s/ //参数不全
Usage:checkAuthorship_2.sh target_dir string.
​
[root@localhost 14_4]# bash checkAuthorship_2.sh /mnt/test/shell/s/ YOU //目录不存在
Dir /mnt/test/shell/s/ does not exits.
​
[root@localhost 14_4]# bash checkAuthorship_2.sh /mnt/test/shell/sed/ YOU
14_4/test.txt: I like YOU but JUST like you
output.txt: I like YOU but just LIKE he 1
test2.txt: I like YOU but just LIKE you 1
test.txt: I like YOU but just LIKE you

从sed输出中设置shell变量

实例1:批量修改文件名脚本:rebane.sh

脚本内容:

[root@localhost 14_4]# cat rename.sh 
#!/bin/bash
​
# 此脚本用来批量重命名当前目录下所有文件
ARGS=2
ONE=1
​
# 检查传递给脚本的参数个数,如果不为2,打印使用方法并退出
if [ $# -ne "$ARGS" ]
then
    echo "Usage: `basename $0` old-pattern new-pattern"
    exit 2
fi
​
number=0
​
# 循环遍历当前目录下所有文件名包含的字符串$1的文件
for filename in *$1*
do
    # 如果指定的文件存在
    if [ -f $filename ]
    then
        # 出除文件路径
        fname=`basename "$filename"`
        # 用新文件名替换旧文件名
        newname=`echo $filename | sed -e "s/$1/$2/g"`
        # 将文件重命名
        mv "$fname" "$newname"
    let "number += 1"
    fi
done
    
# 使用正确的语法
if [ "$number" -eq "$ONE" ] 
then
    echo "$number file renamed"
else
    echo "$number files renamed"
fi
​
exit 0

执行结果:

[root@localhost 14_4]# touch fsx{1..3}
[root@localhost 14_4]# bash rename.sh 
Usage: rename.sh old-pattern new-pattern
[root@localhost 14_4]# bash rename.sh fsx coco
3 files renamed
[root@localhost 14_4]# ls coco*
coco1  coco2  coco3

总结

  • sed是用来解析和转换文本的工具。使用简单,是简介的程序设计语言。

  • sed时由贝尔实验室的李E.麦克马洪在1973年~1974年开发的,并且在大部分操作系统上可以使用

  • sed是非交互式的面向数据流的编辑器

使用sed可以做如下操作:

  1. 自动化编辑一个或多个文件

  2. 简化在多个文件中执行相同编辑的任务

  3. 编写转换程序

  • sed维护一种模式空间,即一个工作区或者临时缓冲区,当使用编辑命令时,将在那里存储单个输入行。

  • sed一次处理一行输入,这使得在读取非常庞大的文件时不会出现内存溢出问题。

  • sed命令的两种语法分别如下

    sed [OPTIONS]... 'COMMAND' [FILE]...
    sed [OPTIONS] -f scriptfile [FILE]...
  • sed常用选项:

    • -e:告诉sed将下一个参数解释为sed指令,只有在命令行上给出多个sed指令才需要使用-e选项

    • -f:指定由sed指令组成的脚本名称。如果sed脚本的第一行位"#n",则sed的行为与指定-n选项相同

    • -i:直接修改读取的内容,而不是输出到终端

    • -n:取消默认输出;一般情况下,sed处理后整个文件内容都会输出到终端,但是使用-n后,只由经过sed处理的行才会被显示出来

  • 在sed中,符号"$"用于只是输出文件中的最后一行或行尾(正则表达)。sed不能直接访问SHELL中的变量,所以必须使用双引号来扩展shell变量。

  • LHS和RHS分别指sed指令汇总的左侧部分和右侧部分。如:替换编辑命令"s/LHS/RHS/"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值