在Linux中,sed命令的完整格式如下:sed[OPTION]...{script-only-if-no-other-script}[input-file]...修改输入文件本身的内容。sed命令是一个流编辑器(streameditor),可以对输入的文本内容进行处理。文本内容可以来自文件或管道。默认情况下,它将处理后的结果打印到标准输出,而不修改文件本身的内容。在mansed中,并没有指定sed命令的处理结果输出到哪里。查看GNUsed的在线帮助说明,提到会打印到标准输出:https://www.gnu.org/software/...sedwritesoutputtostandardoutput.Use-itoeditfilesin-place而不是打印到标准输出。另请参阅W和s///w命令以将输出写入其他文件。以下命令修改file.txt并且不产生任何输出:sed-i's/hello/world/'file.txt即sed默认不会将处理结果写入给定文件。如果要修改文件本身的内容,需要加上-i选项。AddressingAddresses在mansed中,它描述了sed命令如何选择要操作的行:Sed命令可以不带地址,在这种情况下,命令将对所有输入行执行;有一个地址,在这种情况下,命令将只对匹配该地址的输入行执行;或者有两个地址,在这种情况下,将对所有匹配从第一个地址开始并继续到第二个地址的行的包含范围的输入行执行命令。一些例子如下:number:只匹配指定的行号。直接用数字指定要操作的行数/regexp/:匹配正则表达式regexp匹配的行。$:匹配最后一行。删除操作sed使用d命令删除指定行,mansed的说明如下:d删除模式空间。开始下一个循环。下面是几个使用d命令删除输出结果中某些行的例子:输出结果中不打印filename文件的第一行:sed'1d'filenamedoesnotprintthelastlineofthefilenamefilein输出结果,后面的$表示匹配最后一行:sed'$d'filenamedoesnotprintalllinescontainingxmlstringsinthefilenamefileintheoutputresult:sed'/xml/d'filenameorwritethedcommand单引号外sed'/xml/'dfilename注意:写成sed'/*xml*/d'filename不会匹配xml字符串所在的行这与通配符和正则表达式中字符'*'的区别有关。sed命令使用正则表达式来匹配模式,在正则表达式中,'*'表示匹配零个或任意数量的前面字符,而不是表示匹配任何字符串。不要在输出中打印只有一个换行符的空行:sed'/^$/d'filename^表示匹配行首,$表示匹配行尾,首尾之间没有字符行尾,也就是空行。严格来说,这里的“行尾”是指最后一个换行符之前的字符,不包括换行符本身。“空行”实际上仍然包含换行符。不要在输出中打印由空白字符(空格、制表符、换行符、回车符)组成的行:sed'/^[[:space:]]*$/d'filenamehereusesthePOSIXcharacterclass[:space:]表示空白字符,把[:space:]放在[]中,就变成正则表达式,表示匹配[]中的字符,后面加一个*,表示匹配0个或多个前面的字符,即匹配0个或多个空白字符。匹配0个空白字符意味着匹配一个只有换行符的空行。由于sed在处理的时候会先去掉行尾的换行符,所以[:space]这里其实并没有匹配行尾的换行符,而是通过匹配0个空白字符来去掉空行,相当于到/^$/d。注意:此处显示的sed命令不会直接修改给定filename文件本身的内容,而是使用d命令从输出结果中删除匹配的行。如果想直接修改filename文件本身的内容,必须加上-i选项。替换操作sed使用s/regexp/replacement/命令替换匹配特定模式的内容。mansed的描述如下:Attempttomatchregexpagainstthepatternspace。如果成功,则替换与替换匹配的部分。替换可能包含特殊字符&以引用匹配的模式空间部分,以及特殊转义符1到9以引用正则表达式中相应的匹配子表达式。例子如下,下面的sed命令的意思是从标准输入(也就是需要的User输入)读取内容,将输入的foo替换成bar,打印出来。#后面的内容是注释说明,不是命令内容的一部分。$seds'/foo/bar/'#从标准输入接收用户输入,将bar替换为foo并输出afoo#手动输入afoo,然后回车abar#回车后,sed打印输出结果,并显示替换asabarafooF#foo在字符串中间,也会被abarFfoo替换掉#当然完整的foo也会被bar替换掉你可以用这个替换命令把行尾的'r'字符删掉Windows下:sed-i's/\r//'filename对于文本文件,每行以\n\r结尾。在Linux中,每行的最后只有\n,多出的\r往往会造成一些问题。您可以使用此命令将其删除。sed中引用shell变量输入sed命令时,可以引用当前shell定义的变量值,用$来引用即可,但是有一些需要注意的地方:不能用单引号把替换模式括起来,例如“/pattern/command/”应该改为“/pattern/commond”。因为在Bashshell中,单引号不支持扩展,单引号中的$仍然表示'$'字符本身,不代表获取变量的值,不能用${param}来引用变量参数的值。其实bash本身就是通过$获取变量值,变量值展开后,将变量值作为参数传递给sed命令进行处理。获取bash定义变量的值不是由sed命令本身决定的。如果变量名后面没有其他字符,则变量名周围不能放置大括号{}。例如,以下sed命令获取shell的pat变量的值,然后从输出中删除与pat变量的值匹配的行:sed/$pat/dfilename当引用shell变量时,如果该变量name后面跟其他字符,用{}把变量名括起来,防止变量名后面的字符被当成变量名的一部分。比如有一个pat变量,那么$pat获取这个变量的值,${pat}A表示pat变量的值后面有一个字符A,但是$patA表示获取变量的值名为patA。只打印特定的匹配行查看GNUsed的在线帮助链接:https://www.gnu.org/software/...,其中包含以下说明:默认情况下,sed打印所有处理过的输入(已修改的输入除外)/被d)等命令删除。使用-n抑制输出,p命令打印特定行。下面的命令只打印输入文件的第45行:sed-n'45p'file.txt即sed默认打印出处理后的输入内容,可能与原始输入内容不完全相同。sed的一些命令可以修改或删除输入的内容,然后打印出新的内容。打印输出不仅对应于匹配特定模式的行。那些未处理的行将按原样打印。如果只想打印与特定模式匹配的行,请将-n选项与p命令一起使用。例如,使用以下命令只打印后缀为“.xml”的内容:sed-n'/\.xml$/p'这里,\.用于转义和匹配'.'字符,$用于匹配行尾。所以\.xml$对应于.xml扩展名。上面发布的GNUsed帮助链接指定-n选项如下:-n--quiet--silent默认情况下,sed在脚本的每个循环结束时打印出模式空间(请参阅sed工作原理)。这些选项禁用此自动打印,并且sed仅在通过p命令明确告知时才生成输出。看mansed对-n选项的描述:-n,--quiet,--silentsuppressautomaticprintingofpatternspace可以看到我发现mansed中的指令简短而含糊,而网上的指令帮助链接更容易理解,清楚地说明-n选项避免自动打印模式空间的内容。如果发现其他选项在man手册中没有解释清楚,可以查看GNU在线手册的描述。注意:-n选项不会打印与特定模式匹配并已处理的行。例如,将-n选项与d命令一起使用将不会打印任何内容,也不会打印已删除的行。如果只是打印匹配特定模式的行,一般使用grep命令,但是grep命令不能对匹配结果进行二次处理,而sed命令可以进行二次处理,打印特定的匹配行,并进行一些修改。例如,以下命令将后缀为“.cpp”的行替换为“.cc”,并且只打印出这些行:sed-n's/\.cpp$/\.cc/p'forthesedcommand各参数说明如下:“-n”指定不自动打印模式空间的内容,用s命令替换\.cpp$表示匹配“.cpp”后缀名\.cc为替换内容,即“.cc”,最后使用p命令打印处理后的结果。比如输入main.cpp,就会打印出main.cc。注意:cc后面不需要加$。在cpp后面加$是为了匹配行尾,其中$是正则表达式的元字符。如果在cc后面加上$,$会被当成普通字符,成为被替换内容的一部分,即被替换为.cc$,这不是预期的。上面的帮助链接对sed的p命令解释如下:p打印模式空间。从字面上看,p命令是打印模式空间。关键是,模式空间到底是什么。上面帮助链接的“6.1HowsedWorks”部分具体描述了“模式空间”的含义。sed维护两个数据缓冲区:活动模式空间和辅助保持空间。两者最初都是空的。sed通过对每一行输入执行以下循环来运行:首先,sed从输入流中读取一行,删除任何尾随的换行符,并将其放入模式空间。然后执行命令;每个命令都可以有一个与之关联的地址:地址是一种条件代码,只有在执行命令之前验证条件时才会执行命令。到达脚本末尾时,除非-n选项正在使用中,模式空间的内容被打印到输出流,如果它被删除则添加回尾随换行符。然后下一个循环开始下一个输入行。根据这部分的描述,模式空间是一个缓冲区,用于存储要处理的输入行。sed命令会处理这一行,有些命令还会修改这一行的内容。处理完之后,就可以使用p命令打印pattern空间的内容了。由于此内容可能会被修改,因此它可能与原始输入行的内容不完全相同。比如查看上面帮助链接中s命令的说明,可以看到s命令会修改模式空间的内容:s/regexp/replacement/[flags](替换)匹配正则-针对模式空间内容的表达式。如果找到,则用替换替换匹配的字符串。要同时匹配多个模式,可以在sed命令中使用多个-e选项来指定匹配多个模式:sed-e'3,$d'-e's/foo/bar/g'也可以使用a分号(;)分隔多个匹配项:sed'3,$d;s/foo/bar/g'下面的例子说明了该方法的一个应用场景。我们先用find命令找到当前目录下的所有文件名,现在我们要从这些文件名中删除后缀为“.rc”和“.xml”的文件。具体写法如下:sed'/\.rc$/d;/\.xml$/d'文件名使用\.匹配'.'后缀名前面的字符,$表示匹配行尾。所以\.rc$对应.rc后缀,\.xml$对应.xml后缀。lastfilenames保存找到的所有文件名,作为sed要处理的输入内容。使用mansed查看-e选项的说明如下:-escript,--expression=script将脚本添加到要执行的命令中即-e指定执行后面的命令,多个-e即可指定执行多个不同的命令。在mansed中,没有说明分号(;)可以用来分隔多个匹配项。您必须查看infosed中完整的帮助手册以获取相关说明。如果不习惯查看info命令的内容格式,可以在线查看帮助手册,GNUsed主页:http://www.gnu.org/software/sed/其中,HTML的链接帮助手册的版本是:https://www.gnu.org/software/...这个帮助链接解释了使用分号(;)来分隔多个匹配如下,同时也提到了换行符可以用来分离。脚本或脚本文件中的命令可以用分号(;)或换行符(ASCII10)分隔。可以使用-e或-f选项指定多个脚本。由于语法原因,命令a、c、i后面不能跟作为命令分隔符的分号,因此应该以换行符终止或放在脚本或脚本文件的末尾。
