流编辑器sed

sed与grep一样,都起源于老式的ed编辑器,因其是一个流编辑器(stream editor)而得名。与vi等编辑器不同,sed是一种非交互式编辑器(即用户不必参与编辑过程),它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后再输出编辑结果。

sed工作时,首先读取文本中的第1行,将其放入一个被称为模式空间的临时缓冲区内。然后再读取第一条编辑指令,使用指令中定义的模式和行号查找、编辑文本。(这些操作都是针对读入到模式空间里的文本进行的操作,原文本的内容不受影响)完成编辑后,将结果输出并读取下一行,重复这个过程直到文本结束。除了模式空间之外,sed还使用了一个被称为保留空间的临时缓冲区,保留空间通常用于暂存编辑内容。

sed通常用来对多个文件或命令输出进行重复处理,以达到简化操作的目的。它是一个非常重要的文本过滤工具。

一、sed基本格式

  • 命令格式:

sed [option] command input-file

sed [option] –f script-file input-file

上面的命令格式中,展示了sed的两种使用方法。第一种调用方法中,将编辑指令直接放在选项后面,这是最为常见的一种。当执行一些较为复杂的编辑操作时,可能使用的编辑命令会很长,这时为了便于阅读,通常将编辑指令放入一个脚步文件中,通过第2种方法来调用sed编辑文本。

  • 常用选项:

选项用于指定编辑行为、打印设置等,常用的选项如下:

n:不输出所有行,默认情况是输出所有行。

e:允许在该选项后面加一条新的编辑指令。当有多条编辑指令时,应该使用该选项逐一添加,如果编辑指令只有一条,可以不使用该选项。

f:用于指定装有编辑指令的脚本文件。

h:输出sed的帮助信息。

  • 常用的定位方式:

使用sed编辑文本时,应该向其指出要编辑的位置信息,通常使用一个行号或指定一个行号范围,也可以使用正则表达式对要编辑的文本进行模式匹配。常见的操作如下。

n:表示行号为n的行。

m,n:表示一个行号的范围,从第m行到第n行。

m,n!:排除第m行到第n行。

/pattern/:表示匹配pattern的所有行。

/pattern1/pattern2/:表示匹配pattern1和pattern2的所有行(需要使用选项e将两个模式隔开)。

/pattern/,~n:从匹配pattern的行开始,向后的n行(即包括匹配行在内,一共n行)。

/pattern/,+n:从匹配pattern的行开始,加上其后面的n行(即包括匹配行在内,一共n+1行)。

n,/pattern/:表示从第n行开始到匹配pattern之内的所有行。

  • 常用的编辑指令:

使用sed编辑文本时,必须要使用对文本进行操作的指令(称为编辑指令),使用编辑指令可以对文本执行修改、删除和替换等操作。常用的编辑指令及说明如下。

p:将指定的行输出到标准输出。

P:将模式空间中第一个换行符“\n”之前的文本输出到标准输出(选项为大写P)。

=:输出匹配模式所在的行号。

d:移除模式空间中的行并读取下一行。

D:删除模式空间中最后一个换行符之前的文本。如果模式空间为空,则将下一行文本读取到模式空间中。

a\text:在指定的行后面加入新的文本信息text。

i\text:在指定行前面加入新的文本信息text。

c\text:使用新文本信息text替换定位行。

r file:从文件file中读取文本。

w file:将结果写入file文件中。

s/pattern1/pattern2/flag:将与模式pattern1匹配的文本用pattern2替换。默认情况下,只替换第一次匹配到的内容。指令之后的/分隔符可以使用任意字符替代。

n:如果没有禁止默认输出所有行功能(即没有使用选项n),则将模式空间的内容输出到标准输出。如果禁止默认输出功能,就读取下一行文本并替换模式空间中的文本。

N:在当前模式空间中的文本末尾加上换行符\n,并读取下一行文本追加到换行符之后。

!command:对没有被定位的行使用!之后的command编辑指令。

y/pattern1/pattern2/:将与模式pattern1匹配的文本用pattern替换,pattern1和pattern2的字符长度应该相等。

l:将模式空间的文本和控制字符以肉眼可见的方式输出到标准输出。

{sub_command}:执行大括号内的子命令或子命令组。

g:清除模式空间并将保留空间的文本放进模式空间(即模式空间<保留空间)

G:将保留空间的文本追加到模式空间的文本之后(即模式空间<<保留空间)

h:清除保留空间并将模式空间的文本放入保留空间(即模式空间>保留空间)

H:将模式空间的文本追加到保留空间的文本之后(即模式空间>>保留空间)

x:保留空间的文本和模式空间的文件进行互换。

Q:退出指令。使用q指令可以让sed立即退出,不再执行后面的操作。

在上面的编辑指令中,替换匹配模式指令s的flag选项通常向sed指示如何替换或替换成功后要进行的操作。常见的flag选项如下:

g:将所有匹配到的内容全部替换。

n:仅对行内第n次匹配到的内容进行替换。

p:如果进行了替换,就将模式空间的文本输出到标准输出。

w file:如果进行了替换,就将模式空间的文本写入文件file中。

一个编辑指令只能对指定位置进行一次编辑操作,如果要对指定位置执行多次编辑操作,可以使用大括号{}将多条编辑指令放入其中。而对多个位置进行多次编辑可以使用e选项添加多条编辑指令,也可以使用管道并配合多个sed命令。

  • 常用的分支语句:

:label :标记点。标记一个位置以便于跳转语句跳转到指定位置。可以使用任何8个或少于8个字符的字符串来做标记点。

t label:测试指令,如果上一条替换指令成功执行,则转移到标记点label处继续执行。如果没有label,则转移到末尾。

b label:无条件转移到标记点label处继续执行。如果没有label,则转移到末尾。

#:一般用于脚本的注释。将#号后面的内容视为注释,sed将忽略后面的内容,直接执行下一行。如果出现在脚本的第1行,且后面是n(即#n),sed将不禁止默认地输出所有行。

使用了分支语句的编辑指令通常都很长,一般将这些指令放在脚本文件中,然后使用f选项调用sed。

二、显示和删除行

sed命令执行结束后,通常将结果输出到屏幕上,如果需要保存sed命令的输出结果,可以使用输出重定向的方法。

说明:通常将编辑指令放入单引号中,以便于阅读及屏蔽某些特殊字符。

1、显示行

显示行需要使用sed的编辑命令p,指定显示内容可以使用行号、行号范围、正则表达式等。

(1)使用数字3指定输出文本的第3行:

#使用数字3指定输出的行号
#由于sed默认输出所有行,因此使用选项n屏蔽掉默认的输出
[root@localhost zhu]# sed -n '3p' students 
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80

(2)输出指定的行时,也可以指定一个输出范围,例如输出第3行到第5行:

[root@localhost zhu]# sed -n '3,5p' students 
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89

(3)大多时候可能我们并不知道要输出的具体行号,此时可以使用模式匹配的方式定位要输出的行。例如要输出所有辅导员是Tangwei的学生情况:

[root@localhost zhu]# sed -n '/[tT]angwei/p' students 
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65

(4)可以同时使用行号和模式匹配来指定要输出的行。例如输出从第2行开始到匹配含有Hetao的行之间的所有文本:

[root@localhost zhu]# sed -n '2,/Hetao/p' students 
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84

(5)可以使用行首或行尾匹配来指定要输出的行。例如要查找所有2009年入学的学生情况:

[root@localhost zhu]# sed -n '/^29/p' students 
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65

(6)如果要查找某个匹配行的位置,可以不输出匹配行的内容,只输出匹配行的行号。例如要输出西藏的学生在哪行:

[root@localhost zhu]# sed -n '/Xizang/=' students 
6

(7)也可以匹配一行,然后输出匹配行下面n行之内的所有行。例如含有Luolei的行和其后的1行内容:

[root@localhost zhu]# sed -n '/Luolei/,~2p' students 
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84

2、删除行

许多时候我们希望能够删除文本中的内容(类似于grep命令中的反转查找),此时可以使用编辑指令d删除匹配的行。

(1)删除所有2008年入学的学生信息:

#由于指令d会删除模式空间中的内容,因此可以不使用选项n
[root@localhost zhu]# sed '/^28/d' students 
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80
执行上面的删除操作只是在模式空间里进行的,对students文件里内容没有影响
[root@localhost zhu]# cat students 
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80
[root@localhost zhu]# sed -n '/^28/d' students 
[root@localhost zhu]#

这里匹配以28开头的所有文本都被删除了,如果使用n选项将不会有任何输出。

(2)在进行删除时,如果有多个要匹配的条件,此时可以配合使用e选项添加多个编辑指令。例如删除所有匹配lixia和Shanxi的行:

[root@localhost zhu]# sed -ne '/[Ll]ixia/d' -e '/Shanxi/d' -e p students 
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80

执行上面这条指令时,sed将会按选项e指定的编辑指令顺序依次执行。

(3)也可以像显示行那样,使用行号范围删除行。例如需要删除前3行:

[root@localhost zhu]# sed '1,3d' students 
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80

3、插入和修改文本

在指定的行进行插入时,可以使用编辑指令a和i,而替换行则使用编辑指令c。如果插入和替换的内容不止一行,可以在非最后一行使用反斜线“\”符号表示插入的内容并未结束。格式如下:

[指定的行或模式][aic\]
The first line.\
The second line.\
...
The last line.

在上面的格式中,要插入或替换的文本可以位于一行,但是必须用\n来指定换行的位置。编辑指令后的反斜线指定了文本的起始位置。除此之外,为了避免sed引起误解,通常将编辑指令和文本放入单引号中。

(1)例如想要在第1行后面插入新的一行:

[root@localhost zhu]# sed '1a\This is a new line.' students 
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
This is a new line.
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80

注意:执行插入和修改行操作时,如果不使用行号和匹配模式指定要编辑的行,sed会编辑文本的每一行。

(2)也可以使用行首和行尾匹配来定位要插入新文本的位置。例如要在最后一行插入以个新行:

[root@localhost zhu]# sed '$a\This is a new line.' students 
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80
This is a new line.

(3)如果使用的多行文本位于同一行,需要在每一个需要断行的位置加入换行符\n:

[root@localhost zhu]# sed '3a\The first line.\nThe second line.' students 
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
The first line.
The second line.
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80

(4)从上面几个示例可以看出,插入多行时命令可读性很差,因此通常将编辑指令和文本放入一个脚本文件内,通过f选项调用sed进行编辑。

例如使用编辑指令i在匹配Hetao的行前面插入多行内容:

[root@localhost zhu]# cat insert.sed
/Hetao/i\
The first line.\
The second line.\
The last line.
[root@localhost zhu]# sed -f insert.sed students 
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
The first line.
The second line.
The last line.
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80

(5)如果要插入的是一个很长的文本,可以使用r指令将要插入的文本读取后再执行插入操作。例如要将文件ex中的文本插入到第3行之后:

[root@localhost zhu]# sed '3r ex' students 
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
2721020321 Xuli         Jiangsu Luolei  12/25/92        76 81 85 79 321 80
The first line.
The second line.
The last line.
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
2721010409 Liwei        Sichuan tangwei 11/21/92        98 88 85 85 356 89
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
2721030227 Wangtao      Yunnan  Huli    03/21/93        87 76 69 88 320 80

由于使用r指令是直接将一个文件中的文本插入到另一个文本,因此不需要在每一行的结尾加上反斜线。

(6)如果要使用sed替换整行,通常使用编辑指令c。下面是一个使用编辑指令c修改行的示例,首先匹配所有以27开头的行,然后使用c指令将所有匹配到的行替换成新的内容,最后将输出结果重定向到文件file1中:

[root@localhost zhu]# cat modify.sed
/^27/c\
This line was modified.
[root@localhost zhu]# sed -f modify.sed students >file1
[root@localhost zhu]# cat file1
2821020225 Liulu        Sichuan Lixia   01/23/93        89 76 88 72 325 81
2821020115 Liumin       Henan   lixia   05/14/94        78 65 59 78 280 70
This line was modified.
2921020632 Xiayu        Shanxi  Hetao   03/26/93        78 86 92 78 334 84
This line was modified.
2921050313 Heli         Xizang  Tangwei 07/12/94        56 78 80 45 259 65
This line was modified.

提示:在定位的位置插入新行时,只能使用行号和匹配模式指定要编辑的行,不能指定一个范围。

4、替换文本和其他编辑指令

sed提供了两个用于替换文本的编辑指令s和y,它们的使用方法相似但功能却不同。

它们的格式如下:

s/pattern1/pattern2/flag

y/pattern1/pattern2/

s指令将匹配到的pattern1用pattern2替换,y指令的功能与其很相似,不同的是y指令要求匹配的模式与用来替换的文本的字符数长度必须相等。

示例文本students2:

[root@localhost zhu]# cat students2
2821020225##Liulu$$0::A**B&&0\\
2821020115##Liumin$$B::C**0&&0\\
2721020321##Xuli$$0::0**B&&D\\
2921020632## Xiayu$$0::0**0&&0\\
2721010409##Liwei$$C::0**0&&0\\
2921050313##Heli$$A::0**A&&B\\
2721030227## Wangtao$$B::B**C&&0\\

(1)执行替换操作

首先需要整理这个文件,使用制表符Tab替换所有学号和姓名中间的井号#。要将所有#都替换掉,s编辑指令的flag选项应该使用g:

#使用指令s的flag选项g执行全文替换
#使用反斜杠屏蔽井号的特殊意义
#命令中空白为Tab制表符
[root@localhost zhu]# sed 's/\#\#/       /g' students2 | tee students2.1
2821020225       Liulu$$0::A**B&&0\\
2821020115       Liumin$$B::C**0&&0\\
2721020321       Xuli$$0::0**B&&D\\
2921020632       Xiayu$$0::0**0&&0\\
2721010409       Liwei$$C::0**0&&0\\
2921050313       Heli$$A::0**A&&B\\
2721030227       Wangtao$$B::B**C&&0\\

提示:在命令提示符中输入制表符Tab的方法是先按住Ctrl键,再按v键,然后松开v键,再按Tab键松开Ctrl键,最后松开Tab键。

(2)继续使用Tab将其他的字符替换掉:

[root@localhost zhu]# cat replace.sed 
s/\$\$/         /g
s/\:\:/ /g
s/\*\*/ /g
s/\&\&/ /g
s/\\*$//g
[root@localhost zhu]# sed -f replace.sed students2.1 | tee students2.2
2821020225      Liulu           0       A       B       0
2821020115      Liumin          B       C       0       0
2721020321      Xuli            0       0       B       D
2921020632      Xiayu           0       0       0       0
2721010409      Liwei           C       0       0       0
2921050313      Heli            A       0       A       B
2721030227      Wangtao         B       B       C       0

上面的这个示例中,为了保证对齐,在替换姓名后面的$符号时,使用了两个Tab。脚本最后一行,使用了"s/\\*$//g”,其中“\\*$”表示在行尾匹配一个或多个“\”,没有指定用任何字符进行替换,就表示需要删除行尾的“\”符号。

(3)有时需要查看一些肉眼无法看见的控制字符,此时可以使用编辑指令l以肉眼可以看见的方式输出控制字符。例如:

[root@localhost zhu]# sed -n '1,3l' students2.2
2821020225\tLiulu\t\t0\tA\tB\t0$
2821020115\tLiumin\t\tB\tC\t0\t0$
2721020321\tXuli\t\t0\t0\tB\tD$

(4)对指定行之外的行或模式匹配之外的行进行操作,此时可以使用“!”指定需要排除的行。

例如显示除了行号为1 之外的行:

[root@localhost zhu]# sed -n '1!p' students2.2
2821020115      Liumin          B       C       0       0
2721020321      Xuli            0       0       B       D
2921020632      Xiayu           0       0       0       0
2721010409      Liwei           C       0       0       0
2921050313      Heli            A       0       A       B
2721030227      Wangtao         B       B       C       0

(5)在一行执行多次编辑,此时将多个编辑指令放入大括号{}内。例如将实践课成绩中含义A或B的先输出,其他的后输出:

[root@localhost zhu]# sed -n '/^2/{/[AB]/p; /[AB]/!H; $g; $p}' students2.2
2821020225      Liulu           0       A       B       0
2821020115      Liumin          B       C       0       0
2721020321      Xuli            0       0       B       D
2921050313      Heli            A       0       A       B
2721030227      Wangtao         B       B       C       0

2921020632      Xiayu           0       0       0       0
2721010409      Liwei           C       0       0       0

对上面命令的解释:首先匹配以2开头的行,如果匹配,则执行{}内的语句块(大括号内用分号;将各个独立的语句行分开)。当一条匹配行被送进大括号时,如果该行有A或B则打印;如果该行没有A或B则将该行追加到保留空间内;如果该行是最后一行则用保留空间的文本替换模式空间的文本,如果不是最后一行则匹配下一行;$p打印被前面的指令$g替换后的模式空间的文本。

由于保留空间的第1行为空,且使用的是H指令(追加到保留空间),因此在输出中第6行为空。

将上面这条命令拆开等同于:

[root@localhost zhu]# sed -ne '/[AB]/p' -e '/[AB]/!H' -e '$g' -e '$p' students2.2
2821020225      Liulu           0       A       B       0
2821020115      Liumin          B       C       0       0
2721020321      Xuli            0       0       B       D
2921050313      Heli            A       0       A       B
2721030227      Wangtao         B       B       C       0

2921020632      Xiayu           0       0       0       0
2721010409      Liwei           C       0       0       0

(6)将A B C D转换为数字:

[root@localhost zhu]# sed -e 's/A/85/g' -e 's/B/75/g' -e 's/C/60/g' -e 's/D/50/g' students2.2 | tee students2.3
2821020225      Liulu           0       85      75      0
2821020115      Liumin          75      60      0       0
2721020321      Xuli            0       0       75      50
2921020632      Xiayu           0       0       0       0
2721010409      Liwei           60      0       0       0
2921050313      Heli            85      0       85      75
2721030227      Wangtao         75      75      60      0

(7)使用s指令替换文本时,可以使用符号&(与单词and读音相同)表示匹配的文本行本身。例如使用s指令匹配并插入内容:

[root@localhost zhu]# cat bj
Welcome to beijing!
[root@localhost zhu]# C2=Welcome
[root@localhost zhu]# sed -n "s/$C2/Hello! &/p" bj
Hello! Welcome to beijing!

注意:由于单引号会忽略变量引用符号的引用功能,因此如果在sed编辑指令中使用了变量,就不能将编辑指令放入单引号内。

(8)相对于s而言,替换指令y使用相对较少。

sed "y/123/abc/" file

上述替换规律:把file中的1替换成a;2替换成b;3替换成c。注意其对应关系。

(9)编辑命令y的一个重要用途就是用来转换大小写,例如:

[root@localhost zhu]# cat bj
Welcome to beijing!
[root@localhost zhu]# sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' bj
WELCOME TO BEIJING!

5、处理文本中的控制字符

许多人比较喜欢在Windwos系统中使用文本编辑器编写脚本(例如UltrEdit编辑器等),然后将编写好的脚本使用共享、SFTP等方式传递到Linux系统上执行。这时可能这些文本中存在一些控制字符,这些控制字符可能会影响脚步的运行或文档的使用(Linux系统不能识别Windows中的部分字符)。因此在使用这些文本之前应该删除这些控制字符。

要删除文本中的控制字符,首先应该查看文本中的控制字符。通常可以使用cat命令的v选项查看这些肉眼看不见的控制字符:

[root@localhost test]# cat -v hello.sh
#!/bin/bash^M
#this is a test script^M
^M
echo "Hello"^M

在上面的示例中,“^M”就是一个控制字符,删除这些控制字符的思路是使用s将其删除,但在删除之前必须要能产生一个相同的控制字符。

此处以产生“^M”控制字符为例:在终端下先按住Ctrl键,然后再按下V键,此时终端上将不会有任何字符显示。然后松开V键,并按下M键,此时可以看到屏幕上已经产生了控制字符^M,最后松开Ctrl键和M键即可完成输入。

使用如下命令删除文本中的控制字符:

[root@localhost test]# sed 's/^M//g' hello.sh >hello1.sh
[root@localhost test]# cat -v hello1.sh
#!/bin/bash
#this is a test script

echo "Hello"

示例命令中的^M一定要手动输入,不可复制粘贴。

posted @ 2013-12-07 19:35  ITtecman  阅读(1582)  评论(0编辑  收藏  举报