10 shell流编辑sed

来源:互联网 发布:知乎 马蓉限制出境 编辑:程序博客网 时间:2024/05/17 07:56

10.1  sed命令及其语法
sed命令是将一系列的编辑命令应用于一批文本的理想工具。sed命令拥有非交互式和高效的特点,可以为用户节约大量的时间。本节将介绍sed命令的基础知识。

10.1.1  sed命令以及语法
sed命令是一个非交互式的文本编辑器,它可以对来自文本文件以及标准输入的文本进行编辑。其中,标准输入可以是来自键盘、文件重定向、字符串、变量或者是管道的文本。
sed命令会从文件或者标准输入中一次读取一行数据,将其复制到缓冲区,然后读取命令行或者脚本的编辑子命令,对缓冲区中的文本行进行编辑。重复此过程,一直到所有的文本行都处理完毕。


10.1.2  sed命令的工作方式
首先,用户可以在命令行直接执行sed命令,其基本语法如下:
sed [options] commands inputfile
其中commands请参考10.2节内容,,每一个commands由"定位 sed操作 可选参数"组成;其中定位可以省略,可选参数也可以根据实际情况省略;如果省略了定位将对所有行进行操作,否则只对匹配到的行进行操作;
定位分为:1.行号定位;2.正则表达式定位;

sed命令的选项
-n  取消默认输出,只输出定位匹配到的行
-e  允许执行多个子命令
-f  从脚本中读取命令
-i  直接修改原始文件
-l  指定行的长度
-r  在脚本中使用扩展的正则表达式
-u  最低限度的缓存输入与输出

总之,sed命令的使用方式为
sed [sed命令的选项(可选)] "定位部分(可选) sed的操作命令 [sed操作的(可选)参数]" sed操作的文件名


其次,用户可以将sed操作命令写入脚本文件,然后通过sed命令读取该文件并且执行其中的命令,其基本语法如下:
sed [options] -f script inputfile
最后,用户通过将sed的操作命令写入文件,然后将该脚本文件授予用户执行权限,其基本语法如下:
./scrpt inputfile
其中,script代表保存sed命令的脚本文件。在前面已经讲过,在脚本文件中,用户应该在#!符号后面执行该脚本的解释器,因此在这种方式下,sed脚本文件的第一行应该如下:
#! /bin/sed

10.1.3  使用行号定位文本行
1.定位某个特定的行,语法如下:
x
2.定位某段连续的行,语法如下:
x,y
3.指定起始行和步长
first~step
4.指定文件的第一行和最后一行
第1行:
1
最后1行:
$
5.指定某行后面的几行,语法如下:
x,+n

10.1.4  使用正则表达式定位文本行
除了使用行号定位文本行之外,sed命令还支持正则表达式定位。
sed命令中,正则表达式的语法如下:
/regexp/

两个斜线之间的regexp表示正则表达式,其中常用的正则表达式字符如下
普通字符   字符本身就匹配字符本身,如/abc/就定位包含abc的行
.          匹配任意字符
^          匹配行首字符
$          匹配行尾字符
[]         匹配方括号中的任意单个字符
[^]        匹配不出现在方括号中的任意单个字符
\n         匹配换行符
*          表示前置表达式重复了0次或多次
+          表示前置表达式重复了1次以上
?          表示前置表达式重复了0次或1次
{i}        表示前置表达式重复出现i次
{i,}       表示前置表达式至少重复出现i次
{i,j}      表示前置表达式至少匹配i次,最多匹配j次
匹配会扩展到可能的最长的文本量

注意$字符在正则表达式中匹配行尾,在行号定位中表示最后一行

10.2  sed命令的常用操作
除了定位参数之外,sed命令的另外一个组成部分就是编辑命令。常用的编辑命令有打印、插入、删除以及替换等,本节将介绍如何在sed命令使用这些编辑命令。
10.2.1  sed编辑命令基本语法
sed命令的基本语法如下:
[address1[,address2]] cmd [argument]
即"定位 sed操作 可选参数"共同组成sed的编辑命令command;
使用时,在command前加上sed的选项,后面加上操作的文件;

10.2.2  选择文本
在sed命令中,选择文本行主要通过位置参数来完成,基本语法如下:
[address1[ ,address2]] p
在上面的语法中,address1和address2都是位置参数。如果省略位置参数,则表示选择整个文件。子命令p表示将缓冲区中的文本行执行输出操作,即打印(print)缓冲区中的文本。
在上面的命令中只有"定位 sed操作(p打印)",省略了操作的参数;

#! /bin/bash
#输出1~3行,不使用-n选项
sed '1,3p' students.txt
echo "===================================="
#输出1~3行,使用-n选项
sed -n '1,3p' students.txt

#! /bin/bash
#使用正则表达式定位
result=`sed -n '/^20020017/ p' students.txt`
echo "$result"

10.2.3  替换文本
使用sed命令,可以很方便地对文本文件中指定的文本进行替换操作。文本的替换需要使用s子命令,其语法如下:
[address1[ ,address2]] s/pattern/replacemen/[flag]
在上面的语法中,address1与address2都是位置参数,关于它们的用法请参见前面的几个小节。在s命令中,位置参数通常会被省略,表示在所有的文本行中进行替换操作,其语法如下:
s/pattern/replacemen/[flag]
s子命令表示执行替换(substitute)操作。pattern为使用正则表达式表示的匹配模式,replacement为用来替换的由一般字符组成的字符串,如果含有&则表示引用模式(子字符串)。

在s命令中,斜线/是参数分隔符,各个参数之间并不一定要使用斜线/分割,还可以使用出空格以及换行符以外的其他任意字符;s命令会将紧跟在后面的那个字符作为参数分隔符;

flag为替换标志,会影响到s命令的行为
g            全局匹配,会替换文本行中所有符合规则的字符串
n十进制数字  表示替换第n个符合规则的字符串
p            替换第1个符合规则的字符串,并输出到标准输出
w            替换第1个符合规则的字符串,并写入到磁盘文件
空           默认替换第1个符合规则的字符串;

#! /bin/bash
echo "substitute the first pattern."
#只将每行中第1次出现的小写字母e替换为大写字母E
result=`sed 's/e/E/' students.txt`
echo "$result"
echo "substitute all the patterns."
#将每一处的小写字母e都替换为大写字母E
result=`sed 's/e/E/g' students.txt`
echo "$result"


#! /bin/bash
#替换第1~3行中的所有的小写字母e为大写字母E
result=`sed '1,3 s/e/E/g' students.txt`
echo "$result"

#! /bin/bash
#使用混合位置参数
result=`sed '1,/^200200167/ s/e/E/g' students.txt`
echo "$result"

#! /bin/bash
#将文件中的HTML标记替换为空
result=`sed 's/<[^>]*>//g' html.txt`
echo "$result"

#! /bin/bash
#引用与模式相匹配的子串
result=`sed 's/string/long &/' demo1.txt`
echo "$result"

#! /bin/bash
#通过数字来引用模式中的子串
result=`sed 's/\(This\) \(is\) \(a\) \(string\)/\2 \1 \3 \4/' demo1.txt`
echo "$result"

10.2.4  删除文本
sed提供了d子命令来实现文本行的删除(delete),其语法如下:
[address1[ ,address2]] d
在上面的语法中,2个位置参数的涵义以及用法请参见前面的内容。
命令d表示删除位置参数指定的行。如果省略位置参数,则表示删除文本文件中的所有的行。
在执行删除操作时,sed命令的会首先读取一行文本到缓冲区,然后将符合位置参数的文本行删除,接着再读取并处理下一行。下面的例子演示了如何删除指定的文本行。

#! /bin/bash
#删除第1行
result=`sed -e '1 d' students.txt`
echo "$result"

#! /bin/bash
#删除最后一行
result=`sed -e '$ d' students.txt`
echo "$result"

#! /bin/bash
#删除1~4行
result=`sed -e '1,4 d' students.txt`
echo "$result"
echo "==============================="
#删除奇数行
result=`sed -e '1~2 d' students.txt`
echo "$result"
echo "=============================="
#删除偶数行
result=`sed -e '0~2 d' students.txt`
echo "$result"
echo "============================="
#删除从第1行开始,一直到以200200172开头的行
result=`sed -e '1,/^200200172/ d' students.txt`
echo "$result"
echo "============================"
#删除从第4行开始,一直到最后一行的所有行
result=`sed '4,$ d' students.txt`
echo "$result"

10.2.5  追加文本
所谓追加文本,是指将某些文本插入到某个位置的后面。sed命令提供了a子命令来实现文本的追加(append),其基本语法如下:
[address1] a string
从上面的语法可以得知,子命令a最多只能使用一个位置参数。参数string表示将要追加的文本。a子命令会将string代表的文本插入到address1所表示的位置的后面。这一点也是追加文本与后面将要介绍的插入文本的区别。

#! /bin/bash
#在第2行后面追加文本
result=`sed '2 a 200200109      Tom' students.txt`
echo "$result"

#! /bin/bash
#在以200200110开头的文本行后面追加文本
result=`sed '/^200200110/ a 200200109    Tom' students.txt`
echo "$result"

10.2.6  插入文本
插入文本的操作与追加文本非常相似,只是插入的位置不同。
追加文本是在位置参数指定的位置的一行后面插入文本,而插入文本则是位置参数指定的位置的一行前面插入文本。在sed命令中,子命令i用来实现文本的插入,其语法如下:
[address1] i string
与子命令a一样,子命令i也是最多只能使用一个位置参数。位置参数address1用来指定要插入文本的位置,子命令i表示当前的操作是插入文本,参数string表示将要被插入的文本。

#! /bin/bash
#在以200200110开头的文本行前面插入文本
result=`sed '2 i 200200109      Tom' students.txt`
echo "$result"

10.3  组合命令
sed命令支持将多个子命令组合在一起使用,这一点非常重要,因为在通常情况下,用户需要对文本进行多个不同的操作。如果不支持组合命令的话,则需要使用多个sed命令来完成;如果使用组合命令,则可以在一条sed命令中将这些操作完成。本节将介绍sed中的组合命令的使用方法。

10.3.1  使用-e选项执行多个子命令
sed命令的-e选项可以使得sed将跟在其后面的字符串作为子命令执行。在前面的绝大部分例子中,由于都是一个子命令,所以将该选项省略。但是,如果想要为sed命令同时指定多个子命令,则必须使用多个-e选项。

#! /bin/bash
#将所有的小写字母e替换为大写字母,然后打印2~3行
result=`sed -n -e 's/e/E/g' -e '2,3 p' students.txt`
echo "$result"

10.3.2  使用分号执行多个子命令
用户还可以使用分号来将各个子命令隔开,其语法如下:
sed -e 'command1;command2...' filename
其中,command1以及command2等表示多个子命令,这些子命令之间用分号隔开。filename参数表示要处理的文本文件。

#! /bin/bash
#使用分号隔开多个子命令
result=`sed -e 's/e/E/g; 2 i 200100001    Ellen' students.txt`
echo "$result"

10.3.3  对一个地址使用多个子命令
在某些情况下,用户需要对同一个地址使用多个子命令,例如,对某个文件的前20行进行多次替换操作等。sed命令提供了对同一个地址使用多个子命令的语法,如下:
address {
    command1
    command2
    command3
    ...
}

#! /bin/bash
#组合命令
result=`sed -n '1,5 {
    s/e/E/g
    s/a/A/g
    2 i 201303009 Tom
    p
}' students.txt`
echo "$result"

10.3.4  sed脚本文件
sed提供了-f选项,通过这个选项,sed命令可以从指定的脚本文件中读取子命令,然后对每个文本行依次执行各个子命令,其语法如下:
sed -f script
其中,script表示sed脚本文件。
sed脚本的语法比较简单,就是将各个子命令依次列出来,不必使用引号。如果将多条子命令写在同一行中,需要使用分号将其隔开。另外,sed脚本文件支持代码注释,如果某一行以#开头,则表示该行为注释。sed脚本的注释仅限于行注释,不能跨行。

0 0
原创粉丝点击