sed命令sed全称是:Stream EDitor(流编辑器。 Linux sed 命令是利用脚本来处理文本文件,sed 可依照脚本的指令来处理、编辑文本文件。Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。
当处理数据时,sed 从输入源一次读入一行,并将它保存到所谓的模式空间pattern space中。所有 sed 的变换都发生在模式空间。变换都是由命令行上或外部 sed 脚本文件提供的单字母命令来描述的。大多数 sed 命令都可以由一个地址或一个地址范围作为前导来限制它们的作用范围。
| 选项 | 含义 |
|---|---|
| -e 脚本命令 | 该选项会将其后跟的脚本命令添加到已有的命令中。 |
| -f 脚本命令文件 | 该选项会将其后文件中的脚本命令添加到已有的命令中。 |
| -n | 默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容,而该选项会屏蔽启动输出,需使用 print 命令来完成输出。 |
| -i | 此选项会直接修改源文件,要慎用。 |
示例:
查看passwd文件的第5到第8行内容
[root@honey-master ~] sed -n '5,8 p' /etc/passwd
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
查看passwd文件中以roo开头的行
[root@honey-master ~] sed -n '/^roo/ p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
忽略大小写,对含有root字符的行打印出来
[root@honey-master ~] sed -n '/root/I p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
直接查看passwd文件
[root@honey-master ~] sed '' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
.......
此时就不要配置-n参数了,因为-n是用来取消自动打印,配合查找规则一起用的
但 p 标记会输出修改过的行,将二者匹配使用的效果就是只输出被替换命令修改过的行
查找passwd文件中有/bin/bash字符串的行
[root@honey-master ~] sed -n '\%/bin/bash% p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
postgres:x:1000:1000::/home/postgres:/bin/bash
| flags 标记 | 功能 |
|---|---|
| n | 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个标记; |
| g | 对数据中所有匹配到的内容进行替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A; |
| p | 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。 |
| w file | 将缓冲区中的内容写到指定的 file 文件中; |
| & | 用正则表达式匹配的内容进行替换; |
| \n | 匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。 |
| \ | 转义(转义替换部分包含:&、\ 等)。 |
| I | 打印数据流中的文本和不可打印的ASCII字符(比如结束符s、制表符\t) |
| y | 字符转换,转换之后的字符长度必须相同 |
| c | 将选定行内容替换成指定内容 |
| d | 删除,因为是删除啊,所以 d 后面通常不接任何咚咚; |
将 /data/passwd 第2~5行删除打印输出


可以看到这个删除打印,只是在输出时将源文件的2-5行过滤掉,并没有对文件进行任何的修改,如果我要对文件进行修改,就要用到sed -i的命令
删除文件第20行内容 sed -i '20 d' passwd

删除文件之前备份命令
sed -i.bak '20 d' passwd

在文件passwd上的第四行后面添加新字符串 ‘ivanlee’
[root@honey-master data] sed -e 4a\ivanlee passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
ivanlee
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
在文件中的第一行前面追加一个‘ivanlee’
[root@honey-master data] sed '1 i\huawei' passwd
huawei
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
上面两个命令都对文件没有任何的修改,只是在打印时加了条件
如果我想要在文件第一行就插入‘huawei’
第一行起始位置插入
[root@honey-master data] sed -i '1i huawei' passwd
[root@honey-master data] cat -n passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
3 bin:x:1:1:bin:/bin:/sbin/nologin
4 daemon:x:2:2:daemon:/sbin:/sbin/nologin
5 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
7 sync:x:5:0:sync:/sbin:/bin/sync
8 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
第二行末尾插入
[root@honey-master data] sed -i '2a ivanlee' passwd
[root@honey-master data] cat -n passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
3 ivanlee
4 bin:x:1:1:bin:/bin:/sbin/nologin
a和i字符的相同点就是可以单独形成一行,但区别在于a是在一行之后,i在一行之前
sed -e:一次性可以执行多个命令
[root@honey-master data] sed -e 's/huawei/vivo/g; s/ivanlee/Annnnn/g' passwd
1 vivo
2 root:x:0:0:root:/root:/bin/bash
3 Annnnn
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@honey-master data] cat passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
3 ivanlee
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
此命令的基本格式为:
[address]s/pattern/replacement/flags
其中,address 表示指定要操作的具体行,pattern 指的是需要替换的内容,replacement 指的是要替换的新内容。
关于指定具体操作行(address)的用法,这里先不做解释,文章后续会对其做详细介绍。
指定 sed 用新文本替换第几处模式匹配的地方:
[root@honey-master data] sed 's/:/---/3' passwd
huawei
root:x:0---0:root:/root:/bin/bash
ivanlee
bin:x:1---1:bin:/bin:/sbin/nologin
daemon:x:2---2:daemon:/sbin:/sbin/nologin
[root@honey-master data] sed 's/:/---/1' passwd
huawei
root---x:0:0:root:/root:/bin/bash
ivanlee
bin---x:1:1:bin:/bin:/sbin/nologin
daemon---x:2:2:daemon:/sbin:/sbin/nologin
可以看到后面的数字代表的就是在哪个位置发生改变,使用数字 1 作为标记的结果就是,sed 编辑器只替换每行中第 1 次出现的匹配模式。
如果要用新文件替换所有匹配的字符串,可以使用 g 标记:
[root@honey-master data] sed 's/:/---/g' passwd
huawei
root---x---0---0---root---/root---/bin/bash
ivanlee
bin---x---1---1---bin---/bin---/sbin/nologin
daemon---x---2---2---daemon---/sbin---/sbin/nologin
使用w将会把修改后的内容存到命名的文件里

在使用 s 脚本命令时,替换类似文件路径的字符串会比较麻烦,需要将路径中的正斜线进行转义,**sed 's//bin/bash//bin/ivansh/g' passwd **
[root@honey-master data] cat passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
3 ivanlee
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@honey-master data] sed 's/\/bin\/bash/\/bin\/ivansh/g' passwd
1 huawei
2 root:x:0:0:root:/root:/bin/ivansh
3 ivanlee
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
c 命令表示将指定行中的所有内容,替换成该选项后面的字符串。
[root@honey-master data] sed 's/\/bin\/bash/\/bin\/ivansh/g' passwd
1 huawei
2 root:x:0:0:root:/root:/bin/ivansh
3 ivanlee
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@honey-master data] sed '3c ivanlee_changed' passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
ivanlee_changed
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
y 转换命令是唯一可以处理单个字符的 sed 脚本命令
转换命令会对 inchars 和 outchars 值进行一对一的映射,即 inchars 中的第一个字符会被转换为 outchars 中的第一个字符,第二个字符会被转换成 outchars 中的第二个字符...这个映射过程会一直持续到处理完指定字符。如果 inchars 和 outchars 的长度不同,则 sed 会产生一条错误消息。
[root@honey-master data] sed 'y/12345/abcde/' passwd
a huawei
b root:x:0:0:root:/root:/bin/bash
c ivanlee
d bin:x:a:a:bin:/bin:/sbin/nologin
e daemon:x:b:b:daemon:/sbin:/sbin/nologin
[root@honey-master data] cat passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
3 ivanlee
4 bin:x:1:1:bin:/bin:/sbin/nologin
5 daemon:x:2:2:daemon:/sbin:/sbin/nologin
q 命令的作用是使 sed 命令在第一次匹配任务结束后,退出 sed 程序,不再进行对后续数据的处理。
[root@honey-master data] sed '2q' passwd
1 huawei
2 root:x:0:0:root:/root:/bin/bash
只是输出了2行就是因为q命令。
前面在介绍各个脚本命令时,我们一直忽略了对 address 部分的介绍。对各个脚本命令来说,address 用来表明该脚本命令作用到文本中的具体行。
默认情况下,sed 命令会作用于文本数据的所有行。如果只想将命令作用于特定行或某些行,则必须写明 address 部分,表示的方法有以下 2 种:
以上两种形式都可以使用如下这 2 种格式,分别是:
[address]脚本命令
或者
address {
多个脚本命令
}
以上两种形式在前面例子中都有具体实例,因此这里不再做过多赘述。
当使用数字方式的行寻址时,可以用行在文本流中的行位置来引用。sed 会将文本流中的第一行编号为 1,然后继续按顺序为接下来的行分配行号。
在脚本命令中,指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行。这里举一个 sed 命令作用到指定行号的例子:
[root@localhost ~]#sed '2s/dog/cat/' data1.txt
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
可以看到,sed 只修改地址指定的第二行的文本。下面的例子中使用了行地址区间:
[root@localhost ~]# sed '2,3s/dog/cat/' data1.txt
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy dog
在此基础上,如果想将命令作用到文本中从某行开始的所有行,可以用特殊地址——美元符($):
[root@localhost ~]# sed '2,$s/dog/cat/' data1.txt
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy cat
sed 允许指定文本模式来过滤出命令要作用的行,格式如下:
/pattern/command
注意,必须用正斜线将要指定的 pattern 封起来,sed 会将该命令作用到包含指定文本模式的行上。
举个例子,如果你想只修改用户 demo 的默认 shell,可以使用 sed 命令,执行命令如下:
[root@localhost ~] grep demo /etc/passwd
demo:x:502:502::/home/Samantha:/bin/bash
[root@localhost ~] sed '/demo/s/bash/csh/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
demo:x:502:502::/home/demo:/bin/csh
...
虽然使用固定文本模式能帮你过滤出特定的值,就跟上面这个用户名的例子一样,但其作用难免有限,因此,sed 允许在文本模式使用正则表达式指明作用的具体行。正则表达式允许创建高级文本模式匹配表达式来匹配各种数据。这些表达式结合了一系列通配符、特殊字符以及固定文本字符来生成能够匹配几乎任何形式文本的简练模式。
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
我有一个问题。我想从另一个ruby脚本运行一个ruby脚本并捕获它的输出信息,同时让它也输出到屏幕。亚军#!/usr/bin/envrubyprint"Enteryourpassword:"password=gets.chompputs"Hereisyourpassword:#{password}"我运行的脚本文件:开始.rboutput=`runner`putsoutput.match(/Hereisyour(password:.*)/).captures[0].to_s正如您在此处看到的那样,存在问题。在start.rb的第一行,屏幕是空的。我在运行程序中看不到“输入您的密
有这样的事吗?我想在Ruby程序中使用它。 最佳答案 试试这个http://csl.sublevel3.org/jp2a/此外,Imagemagick可能还有一些东西 关于ruby-是否有将图像文件转换为ASCII艺术的命令行程序或库?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6510445/
如何在Ruby的if语句中检查bash命令的返回值(true/false)。我想要这样的东西,if("/usr/bin/fswscell>/dev/null2>&1")has_afs="true"elsehas_afs="false"end它会提示以下错误含义,它总是返回true。(irb):5:warning:stringliteralincondition正确的语法是什么?更新:/usr/bin/fswscell寻找afs安装和运行状态。它会抛出这样的字符串,Thisworkstationbelongstocell如果afs没有运行,命令以状态1退出 最
在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa
关于SSHkit-Github它说:Allbackendssupporttheexecute(*args),test(*args)&capture(*args)来自SSHkit-Rubydoc,我明白execute实际上是test的别名?test之间有什么区别?,execute,capture在Capistrano/SSHKit中我应该什么时候使用? 最佳答案 执行只是执行命令。使用非0退出引发错误。测试方法的行为与execute完全相同,但是它返回bool值(true如果命令以0退出,而false否则)。它通常用于控制任务中的流程
我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解
我正在尝试将cucumber项目的用户名和密码置于版本控制之外。有没有办法在命令行上手动将用户名和密码等变量传递给Cucumber脚本?我的备份计划是将它们放在一个YML文件中,然后将该文件添加到gitignore,这样它们就不会被置于版本控制中。 最佳答案 所以,我看到了您对铁皮人的评论,答案是肯定的。cucumberPASSWORD=my_passwordPASSWORD被设置为环境变量,您可以通过将其引用为ENV['PASSWORD']来使用它的值。例如,browser.text_field(:id=>'pwd').setEN
我想在Windows7上安装带有ruby1.9.3的rspec-railsgem。我收到一些错误消息,提示无法安装某些json库。所以,我使用下面的说明来解决它。来源=The'json'nativegemrequiresinstalledbuildtools从[rubyinstaller.org][3]下载[Ruby1.9.3][2]从[rubyinstaller.org][3]下载DevKit文件对于Ruby1.9.3,使用[DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe][4]将DevKit解压到路径C:\Ruby193\DevKit运行cd