sed的使用

本文介绍了SED流编辑器的基本概念及使用方法,SED作为一种轻量级的文本处理工具,能够高效地通过管道处理数据流。文章详细讲解了SED的基础命令、正则表达式的应用、文本替换等功能,并提供了丰富的示例帮助读者理解和掌握SED的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
sed
参考了以下URL而作的部分翻译
http://www-128.ibm.com/developerworks/linux/library/l-sed1.html
 
Sed编辑器。它有很多点,首先是的,其次它是流编辑器,它可以通stdiopipeline接受数据并编辑。因数据能很容易的通pipe传递给sed,所以sed可以和其他命令一起复杂的文本理功能。
Sed例子
Sed入的数据行任意的用指定的编辑操作(或命令)。Sed是基于行的理,在一行数据上,行所有的命令,并将出到stdout上,然后理下一行。所以它并不修改入文件。
看个例子:
$sed –e ‘d’ /etc/services
条命令,将会没有任何出。因们调用了命令d除行的命令)。Sed文件/etc/services取一行到sedpattern冲区中,除行命令,pattern冲区的内容(内容空,因除)。这种动作重取完文件的内容止。
个例子中,我们应注意到以下几点。首先/etc/services文件并没有被修改。因sed仅仅从文件取内容,并不会降理后的pattern冲区写回文件。其次sed是基于行的。D命令并不会告sed一下子除所有的内容,而是次从文件中取一行到sed内部的pattern冲区中。一旦sed取一行到内部的pattern冲区中,它就d命令,并pattern的内容.后面我将介如何利用address ranges来控制在哪些行上行命令。如果没有指示addresses,在所有行上行命令。第三是使用引号来指示d命令。命令最好用引号来引用,以免shell
sed出流的(出流即文件/ect/services内容)第一行
$sed –e ‘1d’ /etc/services | more
除了命令d前面的1,它和我前面的d命令是一的。1就代表了第一行。D命令前加了可numerical address使用addresses,可以指示sed在哪些行上行命令。
地址范
看看如何指示address range。下例中,sed出的1-10行。
$sed –e ‘1,10d’ /etc/services | more
用逗号分割的两个addresssed将在两个address的行行命令。本例中,sed1-10行,包括1行和10行。
regular expressions来表达地址
如果我想看文件/etc/services文件的内容,但是不想看注。我知道注#开头过滤掉注,我使用sed除以#开头的行。
$sed –e ‘/^#/d’ /etc/services | more
在我分析一下运行机制。除去d命令,就剩下了/^#/,它是一新的regular expression address Regular expression addresses是由/来包着。于匹配了Regular express的行,regular express 之后的命。所以'/^#/'regular expression. 下面来回一下regular expression
可以使用regular expression来表达我找文本的模式。如果你在命令行中曾使用*,你就在使用同regular expression相似的西,但不完全是regular expression下面是在regular expression中常用的字符。
字符
^
匹配一行的始字符
$
匹配一行的束字符
.
匹配任意的个字符
*
匹配0个多个前面的字符
[ ]
匹配[]之中的所有字符
看几个例子 :
regexp
/./
匹配至少包含一个字符的行
/../
匹配至少包含两个字符的行
/^#/
匹配以#开头的行
/^$/
匹配空行
/}^/
匹配以}尾的行
/} *^/
匹配以}尾的行,但}之后可以有任意个空格
/[abc]/
匹配包含小写字符串abc的行
/^[abc]/
匹配以小写字符串abc开头的行
 
可以这样使用regexp
$sed –e ‘/regexp/d’/path/to/my/test/file | more
sed除匹配的所有行。如果告sed打印匹配regexp的行,除不匹配regexp的行的,将更容易理解regexp。如下例子:
$sed –n –e ‘/regexp/p’ /path/to/my/test/file | more
注意新的-n选项,他指示sed不印刷pattern space,除非有示的命令指示他打印。再注意用p代替了命令dp就是print命令。在只有匹配的行被打印。
于地址
到目前,我使用了行地址,行范地址,regexp地址。但是有更多的指示地址的可能。
,分割我可以指示两个regexpsed将在从第一个匹配regexp1的行始,到第一个匹配regexp2的行束的所有行上,行命令。例如,下面的命令将打印从包含BEGIN始,到包含END束的所有行。
$sed –n –e ‘/BEGIN/,/END/p’ /my/test/file | more
如果没有发现BEGIN,将不打印任何数据。如果没有发现END,将打印从包含BEGIN的行始的所有行。是因sedstream-oriented的,它不知道END是否会出
 
如果只想打印c文件中的main函数。可以使用
Sed –n –e ‘/main[[:space:]]*(/,/^}/p’ sourcefile.c | more
命令用到了2regexp/main[[:space:]]*(//^}/1个命令p。第一个regexp将匹配main然后可以有任意个空格,tab,然后是(将匹配ANSI C main函数的声明。
看到[[:space:]]将匹配TABspace[:space:]character classes。他必[]之中。
下面我看第二个regexp’/^}’将匹配以}开头的行。如果代的格式很好的将匹配main函数的
P命令示的告sed打印行,因-n禁止了默的打印功能。
看看sed的最有用的命令,替命令。使用它,我可以替一个特定的字符串,regexp另一个字符串。我看一个最简单的例子:
$sed –e ‘s/foo/bar/’ myfile.txt
命令将第一个foo替换为bar,并将文件的内容输出到stdout。请注意仅仅替换第一个foo,通常这并不是我们想要的。我们想把所有的foo都替换为bar。命令如下:
$sed –e ‘s/foo/bar/g’ myfile.txt
/之后追加的g选项指示sed执行全体替换。我们详细看看’s///’替换命令。首先它是一个命令,仅仅是一个命令。例子中没有指示任何的地址。这意味着替换命令也可以使用地址来控制在哪些行上执行替换。我们看个例子:
$sed –e ‘1,10s/enchantment/entrapment/g’ myfile.txt
这将导致前10行的enchantment被替换为entrapment
$sed –e ‘/^$/,/^END/s/hills/mountains/g’myfile.txt
这个命令将把hills替换为mountains,地址范围为从空行开始,到以END开始的行结束。
关于命令's///'的另一点要说明的是,可以使用很多不同的选项来代替/字符。如果我们的查找串或替代传中包含/的话,我们可以在s字符后面指示不同的分隔符。举个例子,我们将把/usr/local替换为/usr
$sed –e ‘s:/usr/local:/usr:g’mylist.txt
这个例子中,我们使用:作为分隔符。如果你想在regexp中使用分隔符的话,在分隔符的前面加一个/(转意符)
 
到目前为止,我们仅仅执行了简单的字符串替换。尽管很方便,有时我们也需要替换regexp。例如如下的命令将替换<>中间的所有字符为空字符。
$sed –e ‘/<.*>//g’ myfile.txt
这作为删除文件中的HTML tags的第一个尝试,但很遗憾,由于regexp的原因,它并不能正常工作。为什么呢?当sed匹配regexp时,它查找最长的匹配。当使用d,p命令时,这并没有问题。但是当我们使用s命令时,就相当的不同了。我们看个例子:
<b>This</b> is what <b>I</b> meant.
将被替换为:
Meant.
而不是我们期望的
This is what I meant.
幸运的是,我们能够很容易的避免这个问题。修改后的regexp’<[^>]*>’,它指出<后面有任意个非>字符,然后是>字符。其实这执行了可能的最短匹配,而不是最长匹配。修改后的命令为:
$sed –e ‘s/<[^>]*>//g’ myfile.html
例子中[^>]指示了一个非>字符,后面的*指示了任意个非>字符。
关于字符匹配
' []'regexp语法有些额外的选项。为了声明一个字符范围,可以使用开始字符-结束字符来表达。如下例:
‘[a-z]*’
这将匹配任意个小写的az之间的所有字符。
另外'[:space:]' character class用来匹配空白符。
以下是可用的character classes:
Character class
描述
[:alnum:]
字母数字 [a-z A-Z 0-9]
[:alpha:]
字母 [a-z A-Z]
[:blank:]
空白符
[:cntrl:]
控制字符
[:digit:]
数字 [0-9]
[:graph:]
可视字符,不包含空白符
[:lower:]
小写字符[a-z]
[:print:]
非控制字符
[:punct:]
Punctuation characters
[:space:]
空格
[:upper:]
大写字符 [A-Z]
[:xdigit:]
16进制数[0-9 a-f A-F]
应尽可能的利用character classes
 
高级替换
我们可以引用匹配的regexp的部分或全部,以便构建替代字符串。作为例子,我们想在数据的前面添加”ralph said:”,命令如下:
$sed –e ‘s/.*/Ralph said:&/’ origmsg.txt
输出如下:
Ralph said: Hi
Ralph said:
。。。
本例中,我们在替换字符串中使用&,它指示插入匹配的整个regexp。他也可以被多次使用。
/(/)的使用
's///'命令可以在regexp中定义regions,并且在替代字符串中可以引用region。假如有如下文件:
Foo bar oni
Eeny meeny miny
Larry curly moe
现在我们想写脚本把eeny meeny miny替换为victor eeny-meeny von miny。为了做到这一点,我们写一个regexp来匹配由空格分离的三个字符串。
‘.* .* .*’
 
现在我们使用/(/)来包装感兴趣的region.
‘/(.*/) /(.*/) /(.*/)’
这个regexp定义了3个逻辑的region,在替换字符串中可以引用这3region。下面是最终的脚本:
$sed –e ‘s//(.*/) /(.*/) /(.*/)/Victor /1-/2 Von /3/’ myfile.txt
 
正如你看到的,用/x来引用regionx是从1开始的region号。
输出如下:
Victor foo-bar Von oni
Victor eeny-meeny Von miny
Victor larry-curly Von moe
随着你对sed的熟悉,你将能执行强有力的文字处理工作。
 
综合
如果我们编写复杂的脚本,将需要输入更多的命令。有以下几种方法来处理,第一,在命令中使用;分割。例如使用=命令输出行号,p命令来打印。
$sed –n –e ‘=;p’ myfile.txt
命令将被按照顺序,在数据行上被执行。
尽管使用;很方便,也有不能工作的情况。另一个选项时使用-e。例子如下:
$sed –n –e ‘=’ –e ‘p’ myfile.txt
然而,如果更加复杂的追加,插入命令的话,-e可能就不行了。例如对于复杂的多行脚本,最好的方式是使用命令文件。用-f来引用命令文件。
$sed –n –f mycommands.sed myfile.txt
 
同一地址的多个命令
有时需要再一个地址上执行多个命令。在使用’s///’命令替换程序中的字符串时,特别有用。为了在单一地址上执行多个命令,将sed命令保存在文件中,并用{}来将命令分组。
例子如下:
1,20{
        s/[Ll]inux/GNU//Linux/g
        s/samba/Samba/g
        s/posix/POSIX/g
}
例子中对120行中的每一行,执行3个替代命令。当然也可以使用regexp adresses,或者两者的组合。
1,/^END/{
        s/[Ll]inux/GNU//Linux/g
        s/samba/Samba/g
        s/posix/POSIX/g
         p
}
从第一行到以END开始的行或文件的结束行为止的所有行上,执行所有的命令。
追加,插入,改变行
插入行命令如下:
i/
This line will be inserted before each line
如果你没有指出地址的话,它将要在每一行前插入该行。
输出如下:
This line will be inserted before each line
line 1 here
This line will be inserted before each line
line 2 here
This line will be inserted before each line
line 3 here
This line will be inserted before each line
line 4 here
如果想在当前行前插入多行,可以在行结束时加入/
如下所示:
i/
insert this line/
and this one/
and this one/
 
a命令将在当前行后插入一行,
a/
insert this line after each line. Thanks! :)
c命令将替换当前行
c/
You're history, original line! Muhahaha!
 
 
因为append, insert, change命令行需要输入多行命令,所以它需要写入命令文件中。
 
文本转换Text translation
第一个实用脚本是转换unix风格的文本到dos/windows风格。如你所知,dos/windows的文本文件在行结尾有CR(carriage return)LF(line feed),而unix文本文件的每行仅有line feed。如下的脚本将帮你从unix风格到dos/windows风格进行转换。
$sed –e ‘s/$//r/’ myunix.txt > mydos.txt
Regexp中的$代表行的结尾,/r告诉sed在它之前插入carriage return。这样每行是以/r/n结尾的。
如下的脚本完成从dos/windows风格的文本到unix风格的文本的转换:
$sed –e ‘s/.$//’mydos.txt > myunix.txt
我们的脚本匹配每行的最后一个字符,正好是/r,我们将他替换为空。如果你发现最后一个字符被删除了,那么源文件就是unix风格的文本了。
 
行的逆序
Tac命令仅仅把文件的所有行逆序,而每一行的内容不变。
Tacing如下文件:
Foo
Bar
Oni
将产生如下的输出:
Oni
Bar
Foo
我们可以使用如下脚本完成相同的功能:
$sed –e ‘1!G;h;$!d’ forward.txt > backward.txt
我们解释一下该脚本的工作原理,首先它包含了3个命令,由;进行分割。’1!G’,’h’,’$!d’。如果第一个命令是’1G’G命令将仅仅作用在第一行。但是另外的!代表地址的相反,意思是,G作用于除第一行之外的所有行。对于$!d来说,也是相似的。如果命令是 '$d',d将仅仅作用于最后一行,('$' address是指明最后一行的简单方法). 然而,有了!d命令将作用于除最后一行之外的所有行。现在,我们来理解如何进行的逆序。
当我们执行脚本时,首先被执行的是h,(因为G不在第一行上执行)。该命令h拷贝pattern spacehold space(临时的缓冲区)。接着d命令被执行,它从pattern space中删除foo。所以在该行上的所有命令被执行完毕后,并没有打印任何数据。
现在第二行。Bar被读进pattern space之后,G被执行。他将把hold space的内容(”foo/n”)追加到pattern space中(”bar/n”),现在pattern space中的内容为(“bar/nfoo/n”)h命令再把pattern space的内容拷贝到hold space中。D命令删除pattern space中的内容。也不打印任何内容。
最后一行,oni,除了不删除pattern space的内容之外,同样的步骤被执行。逆序后的数据被输出到stdout中。
 
SED(1)                           User Commands                          SED(1)
 
NAME
       sed - stream editor for filtering and transforming text
 
SYNOPSIS
       sed [OPTION]... {script-only-if-no-other-script} [input-file]...
 
DESCRIPTION
       Sed is a stream editor. A stream editor is used to perform basic text
       transformations on an input stream (a file or input from a pipeline).
       While in some ways similar to an editor which permits scripted edits
       (such as ed), sed works by making only one pass over the input(s), and
       is consequently more efficient. But it is sed's ability to filter text
       in a pipeline which particularly distinguishes it from other types of
       editors.
 
       -n, --quiet, --silent
 
              suppress automatic printing of pattern space
 
       -e script, --expression=script
 
              add the script to the commands to be executed
 
       -f script-file, --file=script-file
 
              add the contents of script-file to the commands to be executed
 
       -i[SUFFIX], --in-place[=SUFFIX]
 
              edit files in place (makes backup if extension supplied)
 
       -l N, --line-length=N
 
              specify the desired line-wrap length for the `l' command
 
       --posix
 
              disable all GNU extensions.
 
       -r, --regexp-extended
 
              use extended regular expressions in the script.
 
       -s, --separate
 
              consider files as separate rather than as a single continuous
              long stream.
 
       -b, --binary
 
              do not convert DOS to UNIX lineendings (only on systems support-
              ing different lineendings).
 
       -u, --unbuffered
 
              load minimal amounts of data from the input files and flush the
              output buffers more often
 
       --help display this help and exit
 
       --version
              output version information and exit
 
       If no -e, --expression, -f, or --file option is given, then the first
       non-option argument is taken as the sed script to interpret. All
       remaining arguments are names of input files; if no input files are
       specified, then the standard input is read.
 
       E-mail bug reports to: bonzini@gnu.org . Be sure to include the word
       ``sed'' somewhere in the ``Subject:'' field.
 
COMMAND SYNOPSIS
       This is just a brief synopsis of sed commands to serve as a reminder to
       those who already know sed; other documentation (such as the texinfo
       document) must be consulted for fuller descriptions.
 
   Zero-address ``commands''
       : label
              Label for b and t commands.
 
       #comment
              The comment extends until the next newline (or the end of a -e
              script fragment).
 
       }      The closing bracket of a { } block.
 
   Zero- or One- address commands
       =      Print the current line number.
 
       a /
 
       text   Append text, which has each embedded newline preceded by a back-
              slash.
 
       i /
 
       text   Insert text, which has each embedded newline preceded by a back-
              slash.
 
       q      Immediately quit the sed script without processing any more
              input, except that if auto-print is not disabled the current
              pattern space will be printed.
 
       Q      Immediately quit the sed script without processing any more
              input.
 
       r filename
              Append text read from filename.
 
       R filename
              Append a line read from filename.
 
   Commands which accept address ranges
       {      Begin a block of commands (end with a }).
 
       b label
              Branch to label; if label is omitted, branch to end of script.
 
       t label
              If a s/// has done a successful substitution since the last
              input line was read and since the last t or T command, then
              branch to label; if label is omitted, branch to end of script.
 
       T label
              If no s/// has done a successful substitution since the last
              input line was read and since the last t or T command, then
              branch to label; if label is omitted, branch to end of script.
 
       c /
 
       text   Replace the selected lines with text, which has each embedded
              newline preceded by a backslash.
 
       d      Delete pattern space. Start next cycle.
 
       D      Delete up to the first embedded newline in the pattern space.
              Start next cycle, but skip reading from the input if there is
              still data in the pattern space.
 
       h H    Copy/append pattern space to hold space.
 
       g G    Copy/append hold space to pattern space.
 
       x      Exchange the contents of the hold and pattern spaces.
 
       l      List out the current line in a ``visually unambiguous'' form.
 
       n N    Read/append the next line of input into the pattern space.
 
       p      Print the current pattern space.
 
       P      Print up to the first embedded newline of the current pattern
              space.
 
      s/regexp/replacement/
              Attempt to match regexp against the pattern space. If success-
              ful,   replace that portion matched with replacement.   The
              replacement may contain the special character & to refer to that
              portion of the pattern space which matched, and the special
              escapes /1 through /9 to refer to the corresponding matching
              sub-expressions in the regexp.
 
       w filename
              Write the current pattern space to filename.
 
       W filename
              Write the first line of the current pattern space to filename.
 
       y/source/dest/
              Transliterate the characters in the pattern space which appear
              in source to the corresponding character in dest.
 
Addresses
       Sed commands can be given with no addresses, in which case the command
       will be executed for all input lines; with one address, in which case
       the command will only be executed for input lines which match that
       address; or with two addresses, in which case the command will be exe-
       cuted for all input lines which match the inclusive range of lines
       starting from the first address and continuing to the second address.
       Three things to note about address ranges: the syntax is addr1,addr2
       (i.e., the addresses are separated by a comma); the line which addr1
       matched will always be accepted, even if addr2 selects an earlier line;
       and if addr2 is a regexp, it will not be tested against the line that
       addr1 matched.
 
       After the address (or address-range), and before the command, a !   may
       be inserted, which specifies that the command shall only be executed if
       the address (or address-range) does not match.
 
       The following address types are supported:
 
       number Match only the specified line number.
 
       first~step
              Match every step'th line starting with line first. For example,
              ``sed -n 1~2p'' will print all the odd-numbered lines in the
              input stream, and the address 2~5 will match every fifth line,
              starting with the second. (This is an extension.)
 
       $      Match the last line.
 
       /regexp/
              Match lines matching the regular expression regexp.
 
       /cregexpc
              Match lines matching the regular expression regexp. The c may
              be any character.
 
       GNU sed also supports some special 2-address forms:
 
       0,addr2
              Start out in "matched first address" state, until addr2 is
              found. This is similar to 1,addr2, except that if addr2 matches
              the very first line of input the 0,addr2 form will be at the end
              of its range, whereas the 1,addr2 form will still be at the
              beginning of its range.
 
       addr1,+N
              Will match addr1 and the N lines following addr1.
 
       addr1,~N
              Will match addr1 and the lines following addr1 until the next
              line whose input line number is a multiple of N.
 
REGULAR EXPRESSIONS
       POSIX.2 BREs should be supported, but they aren't completely because of
       performance problems. The /n sequence in a regular expression matches
       the newline character, and similarly for /a, /t, and other sequences.
 
内容概要:本文深入探讨了Kotlin语言在函数式编程和跨平台开发方面的特性和优势,结合详细的代码案例,展示了Kotlin的核心技巧和应用场景。文章首先介绍了高阶函数和Lambda表达式的使用,解释了它们如何简化集合操作和回调函数处理。接着,详细讲解了Kotlin Multiplatform(KMP)的实现方式,包括共享模块的创建和平台特定模块的配置,展示了如何通过共享业务逻辑代码提高开发效率。最后,文章总结了Kotlin在Android开发、跨平台移动开发、后端开发和Web开发中的应用场景,并展望了其未来发展趋势,指出Kotlin将继续在函数式编程和跨平台开发领域不断完善和发展。; 适合人群:对函数式编程和跨平台开发感兴趣的开发者,尤其是有一定编程基础的Kotlin初学者和中级开发者。; 使用场景及目标:①理解Kotlin中高阶函数和Lambda表达式的使用方法及其在实际开发中的应用场景;②掌握Kotlin Multiplatform的实现方式,能够在多个平台上共享业务逻辑代码,提高开发效率;③了解Kotlin在不同开发领域的应用场景,为选择合适的技术栈提供参考。; 其他说明:本文不仅提供了理论知识,还结合了大量代码案例,帮助读者更好地理解和实践Kotlin的函数式编程特性和跨平台开发能力。建议读者在学习过程中动手实践代码案例,以加深理解和掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值