linux---sed命令

2023-11-04

一、sed命令概念

sed编辑器被称作流编辑器( stream editor),和普通的交互式文本编辑器恰好相反。在交互式文本编辑器中(比如vim),你可以用键盘命令来交互式地插入、删除或替换数据中的文本。流编辑器则会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。

它是文本处理中非常有用的工具,能够完美的配合正则表达式使用,处理时,把当前处理的行存储在临时缓冲区中,称为模式空间,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变。

sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。 sed编辑器会执行下列操作。
(1) 一次从输入中读取一行数据。
(2) 根据所提供的编辑器命令匹配数据。
(3) 按照命令修改流中的数据。
(4) 将新的数据输出到STDOUT。

在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据并重复这个过程。在流编辑器处理完流中的所有数据行后,它就会终止。由于命令是按顺序逐行给出的, sed编辑器只需对数据流进行一遍处理就可以完成编辑操作。这使得sed编辑器要比交互式编辑器快得多,你可以快速完成对数据的自动修改。

二、sed命令的格式

sed options script file

选项允许你修改sed命令的行为,可以使用的选项如下表所示:

选项 描述
-e script 在处理输入时,将script中指定的命令添加到已有的命令中
-f file 在处理输入时,将file中指定的命令添加到已有的命令中
-n 不产生命令输出,使用print命令来完成输出
script参数指定了应用于流数据上的单个命令。如果需要用多个命令,要么使用-e选项在命令行中指定,要么使用-f选项在单独的文件中指定。
1、在命令行定义编辑器命令

默认情况下, sed编辑器会将指定的命令应用到STDIN输入流上。这样你可以直接将数据通过管道输入sed编辑器处理。这里有个简单的示例。

[root@localhost ~]# echo "This is a test" | sed 's/test/big test/'
This is a big test
# s命令会用斜线间指定的第二个文本字符串来替换第一个文本字符串模式。在本例中是big test替换了test。
[root@localhost ~]# cat test.txt 
this is root
this is root
this is root
this is redhat
this is redhat 
this is root
this is root
[root@localhost ~]# sed 's/redhat/root/' test.txt 
this is root
this is root
this is root
this is root		# 将redhat替换为了root
this is root 
this is root
this is root

sed命令几乎瞬间就执行完并返回数据。在处理每行数据的同时,结果也显示出来了。可以在sed编辑器处理完整个文件之前就开始观察结果。

重要的是,要记住, sed编辑器并不会修改文本文件的数据它只会将修改后的数据发送到STDOUT。如果你查看原来的文本文件,它仍然保留着原始数据。

2、在命令行使用多个编辑器命令

要在sed命令行上执行多个命令时,只要用-e选项就可以了。

[root@localhost ~]# sed -e 's/this is/there are/; s/root/redhat/' test.txt 
there are redhat	# 将 this is 替换为了 there are
there are redhat	# 同时将 root 替换为了 redhat
there are redhat
there are redhat
there are redhat 
there are redhat
there are redhat

两个命令都作用到文件中的每行数据上。命令之间必须用分号隔开,并且在命令末尾和分号之间不能有空格

如果不想用分号,也可以用bash shell中的次提示符来分隔命令。只要输入第一个单引号标示出sed程序脚本的起始( sed编辑器命令列表), bash会继续提示你输入更多命令,直到输入了标示结束的单引号。

[root@localhost ~]# sed -s '
> s/this is/there are/			# 将 this is 替换为了 there are
> s/root/redhat/' test.txt		# 将 root 替换为了 redhat
there are redhat
there are redhat
there are redhat
there are redhat
there are redhat 
there are redhat
there are redhat
3、从文件中读取编辑器命令

最后,如果有大量要处理的sed命令,那么将它们放进一个单独的文件中通常会更方便一些。可以在sed命令中用-f选项来指定文件。

[root@localhost ~]# cat test.sed 	
s/this/there/
s/is/are/
s/root/redhat/
[root@localhost ~]# sed -f test.sed test.txt 
there are redhat
there are redhat
there are redhat
there are redhat
there are redhat 
there are redhat
there are redhat

在这种情况下,不用在每条命令后面放一个分号。 sed编辑器知道每行都是一条单独的命令。跟在命令行输入命令一样, sed编辑器会从指定文件中读取命令,并将它们应用到数据文件中的每一行上。

我们很容易就会把sed编辑器脚本文件与bash shell脚本文件搞混。为了避免这种情况,可以使用.sed作为sed脚本文件的扩展名。

三、更多的替换选项

前面使用s命令( substitute)来在行中替换文本。这个命令还有另外一些选项能让事情变得更为简单。

1、替换标记

关于替换命令如何替换字符串中所匹配的模式需要注意一点。

[root@localhost ~]# cat test1.txt 
This is a test of the test script.
This is the second test of the test script.
[root@localhost ~]# sed 's/test/trial/' test1.txt 
This is a trial of the test script.
This is the second trial of the test script.

替换命令在替换多行中的文本时能正常工作,但默认情况下它只替换每行中出现的第一处。要让替换命令能够替换一行中不同地方出现的文本必须使用替换标记( substitution flag)。替换标记会在替换命令字符串之后设置。

s/pattern/replacement/flags

有4种可用的替换标记:
  • 数字,表明新文本将替换第几处模式匹配的地方;
  • g,表明新文本将会替换所有匹配的文本;
  • p,表明原先行的内容要打印出来
  • w file,将替换的结果写到文件中

在第一类替换中,可以指定sed编辑器用新文本替换第几处模式匹配的地方。

[root@localhost ~]# sed 's/test/trial/2' test1.txt 
This is a test of the trial script.
This is the second test of the trial script.
# 将第二处模式匹配的地方进行了替换

将替换标记指定为2的结果就是: sed编辑器只替换每行中第二次出现的匹配模式。

g替换标记使你能替换文本中匹配模式所匹配的每处地方。

[root@localhost ~]# sed 's/test/trial/g' test1.txt 
This is a trial of the trial script.
This is the second trial of the trial script.

p替换标记会打印与替换命令中指定的模式匹配的行。这通常会和sed的-n选项一起使用。

[root@localhost ~]# cat test3.txt 
This is a test line.
This is a different line.
[root@localhost ~]# sed -n 's/test/trial/p' test3.txt 
This is a trial line.

-n选项将禁止sed编辑器输出。但p替换标记会输出修改过的行。将二者配合使用的效果就是只输出被替换命令修改过的行。

w替换标记会产生同样的输出,不过会将输出保存到指定文件中。

[root@localhost ~]# sed 's/test/trial/w test.txt' test3.txt
This is a trial line.
This is a different line.
[root@localhost ~]# cat test.txt 
This is a trial line.

2、替换字符

有时你会在文本字符串中遇到一些不太方便在替换模式中使用的字符。 Linux中一个常见的例子就是正斜线( /)。
替换文件中的路径名会比较麻烦。比如,如果想用C shell替换/etc/passwd文件中的bash shell,必须这么做 :

[root@localhost ~]# sed -n 's/\/bin\/bash/\/bin\/csh/p' /etc/passwd
root:x:0:0:root:/root:/bin/csh
redhat:x:1000:1000:redhat:/home/redhat:/bin/csh

由于正斜线通常用作字符串分隔符,因而如果它出现在了模式文本中的话,必须用反斜线来转义。这通常会带来一些困惑和错误。

要解决这个问题, sed编辑器允许选择其他字符来作为替换命令中的字符串分隔符:

[root@localhost ~]# sed -n 's!/bin/bash!/bin/csh!p' /etc/passwd
root:x:0:0:root:/root:/bin/csh
redhat:x:1000:1000:redhat:/home/redhat:/bin/csh

在这个例子中,感叹号被用作字符串分隔符,这样路径名就更容易阅读和理解了。

四、使用地址

默认情况下,在sed编辑器中使用的命令会作用于文本数据的所有行。如果只想将命令作用于特定行或某些行,则必须用行寻址( line addressing)。

在sed编辑器中有两种形式的行寻址:

  • 以数字形式表示行区间
  • 用文本模式来过滤出行

两种形式都使用相同的格式来指定地址:

[address] command

也可以将特定地址的多个命令分组

address {
command1
command2
command3
}

sed编辑器会将指定的每条命令作用到匹配指定地址的行上。下面将会演示如何在sed编辑器脚本中使用两种寻址方法。

1、数字方式的行寻址

当使用数字方式的行寻址时,可以用行在文本流中的行位置来引用。 sed编辑器会将文本流中的第一行编号为1,然后继续按顺序为接下来的行分配行号。

在命令中指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行。这里有个sed命令作用到指定行号的例子。

[root@localhost ~]# sed '2s/root/redhat/' test.txt 
this is root
this is redhat		# 2s 替换第二行的root
this is root		# 3s 则为替换第三行的root
this is root
this is root
this is root

sed编辑器只修改地址指定的第二行的文本。这里有另一个例子,这次使用了行地址区间。

[root@localhost ~]# sed '2,3s/root/redhat/' test.txt 
this is root
this is redhat
this is redhat
this is root
this is root
this is root
2、使用文本模式过滤器

另一种限制命令作用到哪些行上的方法会稍稍复杂一些。 sed编辑器允许指定文本模式来过滤出命令要作用的行。格式如下:

/pattern/command

必须用正斜线将要指定的pattern封起来。 sed编辑器会将该命令作用到包含指定文本模式的行上。

举个例子,如果你想只修改用户redhat的默认shell,可以使用sed命令

[root@localhost ~]# sed -n '/redhat/s/bash/csh/p' /etc/passwd
redhat:x:1000:1000:redhat:/home/redhat:/bin/csh

该命令只作用到匹配文本模式的行上。虽然使用固定文本模式能帮你过滤出特定的值,就跟上面这个用户名的例子一样,但其作用难免有限。 sed编辑器在文本模式中采用了一种称为正则表达式( regular expression)的特性来帮助你创建匹配效果更好的模式。

正则表达式允许创建高级文本模式匹配表达式来匹配各种数据。这些表达式结合了一系列通配符、特殊字符以及固定文本字符来生成能够匹配几乎任何形式文本的简练模式。

3、命令组合

如果需要在单行上执行多条命令,可以用花括号将多条命令组合在一起。 sed编辑器会处理地址行处列出的每条命令。

[root@localhost ~]# sed '2{
> s/this/the/
> s/root/redhat/
> }' test.txt
this is root
the is redhat
this is root
this is root
this is root
this is root
[root@localhost ~]# sed '3,${
> s/this/the/
> s/root/redhat/
> }' test.txt
this is root
this is root
the is redhat
the is redhat
the is redhat
the is redhat

sed编辑器会将所有命令作用到该地址区间内的所有行上。

五、删除行

文本替换命令不是sed编辑器唯一的命令。如果需要删除文本流中的特定行,可以用删除命令。删除命令d名副其实,它会删除匹配指定寻址模式的所有行。使用该命令时要特别小心,如果你忘记加入寻址模式的话,流中的所有文本行都会被删除。

[root@localhost ~]# cat test.txt 
this is root
this is root
this is root
this is root
this is root
this is root
[root@localhost ~]# sed 'd' test.txt 

当和指定地址一起使用时,删除命令显然能发挥出最大的功用。可以从数据流中删除特定的文本行,通过行号指定:

[root@localhost ~]# cat test1.txt 
This is a test of the test script.
This is the second test of the test script.
[root@localhost ~]# sed '2d' test1.txt 
This is a test of the test script.

或者通过特定行区间指定:

[root@localhost ~]# cat test.txt 
this is root1
this is root2
this is root3
this is root4
this is root5
this is root6
[root@localhost ~]# sed '2,4d' test.txt 
this is root1
this is root5
this is root6

或者通过特殊的文件结尾字符:

[root@localhost ~]# sed '4,$d' test.txt 
this is root1
this is root2
this is root3

sed编辑器的模式匹配特性也适用于删除命令。

[root@localhost ~]# sed '/root4/d' test.txt 
this is root1
this is root2
this is root3
this is root5
this is root6

sed编辑器会删掉包含匹配指定模式的行。

记住, sed编辑器不会修改原始文件。你删除的行只是从sed编辑器的输出中消失了。原始文件仍然包含那些“删掉的”行。

也可以使用两个文本模式来删除某个区间内的行,但这么做时要小心。你指定的第一个模式会“打开”行删除功能,第二个模式会“关闭”行删除功能。 sed编辑器会删除两个指定行之间的所有行(包括指定的行)。

[root@localhost ~]# sed '/1/,/4/d' test.txt 
this is root5
this is root6

除此之外,你要特别小心,因为只要sed编辑器在数据流中匹配到了开始模式,删除功能就会打开。这可能会导致意外的结果。

[root@kittod ~]# cat data5.txt 
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 1 again.
This is text you want to keep.
This is the last line in the file.
[root@kittod ~]# sed '/1/,/3/d' data5.txt 
This is line number 4.

第二个出现数字“1”的行再次触发了删除命令,因为没有找到停止模式,所以就将数据流中的剩余行全部删除了。当然,如果你指定了一个从未在文本中出现的停止模式,显然会出现另外一个问题。

因为删除功能在匹配到第一个模式的时候打开了,但一直没匹配到结束模式,所以整个数据流都被删掉了。

插入和附加文本

跟其他编辑器类似, sed编辑器允许向数据流插入和附加文本行。两个操作的区别:

  • 插入(insert)命令 (i)会在指定行前增加一个新行。
  • 附加(append)命令 (a) 会在指定行后增加一个新行。

它们不能在单个命令行上使用。你必须指定是要将行插入还是附加到另一行。格式如下:

sed ‘[address]command
newline’

new line中的文本将会出现在sed编辑器输出中你指定的位置。记住,当使用插入命令时,文本会出现在数据流文本的前面。

[root@localhost ~]# echo "test line 2" |sed 'i\test line 1'
test line 1
test line 2
[root@localhost ~]# echo "test line 1" |sed 'a\test line 2'
test line 1
test line 2

当使用附加命令时,文本会出现在数据流文本的后面。

[root@localhost ~]# echo "test line 1" |sed 'a\test line 2'
test line 1
test line 2

在命令行界面提示符上使用sed编辑器时,你会看到次提示符来提醒输入新的行数据。你必须在该行完成sed编辑器命令。一旦你输入了结尾的单引号, bash shell就会执行该命令。

[root@localhost ~]# echo "test line 1" | sed 'i\
> test line 2'
test line 2
test line 1

这样能够给数据流中的文本前面或后面添加文本,但如果要向要向数据流行内部插入或附加数据,你必须用寻址来告诉sed编辑器你想让数据出现在什么位置。可以在用这些命令时只指定一个行地址。可以匹配一个数字行号或文本模式,但不能用地址区间。这合乎逻辑,因为你只能将文本插入或附加到单个行的前面或后面,而不是行区间的前面或后面。

下面的例子是将一个新行插入到数据流第三行前。

[root@localhost ~]# sed '3i\
> this is newroot' test.txt
this is root1		# 给第三行前插入了新的一行
this is root2
this is newroot
this is root3
this is root4
this is root5
this is root6

下面的例子是将一个新行附加到数据流中第三行后。

[root@localhost ~]# sed '3a\
> this is newroot' test.txt
this is root1		# 给第三行后插入了新的一行
this is root2
this is root3
this is newroot
this is root4
this is root5
this is root6

它使用与插入命令相同的过程,只是将新文本行放到了指定的行号后面。如果你有一个多行数据流,想要将新行附加到数据流的末尾,只要用代表数据最后一行的美元符就可以了。

[root@localhost ~]# sed '$a\
> this is last root' test.txt
this is root1		# 在最后一行插入了新的一行
this is root2
this is root3
this is root4
this is root5
this is root6
this is last root

同样的方法也适用于要在数据流起始位置增加一个新行。只要在第一行之前插入新行即可。要插入或附加多行文本,就必须对要插入或附加的新文本中的每一行使用反斜线,直到最后一行。

[root@localhost ~]# sed '1i\
> This is one line of new text.\
> This is another line of newe text.' test.txt
This is one line of new text.
This is another line of newe text.
this is root1
this is root2
this is root3
this is root4
this is root5
this is root6

指定的两行都会被添加到数据流中。

六、修改行

修改( change)命令允许修改数据流中整行文本的内容。它跟插入和附加命令的工作机制一样,你必须在sed命令中单独指定新行。

[root@localhost ~]# sed '3c\
> this is newroot3' test.txt
this is root1
this is root2
this is newroot3
this is root4
this is root5
this is root6

在这个例子中, sed编辑器会修改第三行中的文本。也可以用文本模式来寻址。

[root@localhost ~]# sed '/root4/c\
> this is newroot4' test.txt
this is root1
this is root2
this is root3
this is newroot4
this is root5
this is root6

文本模式修改命令会修改它匹配的数据流中的任意文本行。

你可以在修改命令中使用地址区间,但结果未必如愿。

[root@kittod ~]# sed '2,3c\
> This is a new line of text.' data4.txt
This is line number 1.
This is a new line of text.
This is line number 4.

sed编辑器会用这一行文本来替换数据流中的两行文本,而不是逐一修改这两行文本。

七、转换命令

转换( transform)命令( y)是唯一可以处理单个字符的sed编辑器命令。转换命令格式如下。

[address]y/inchars/outchars/

转换命令会对inchars和outchars值进行一对一的映射。 inchars中的第一个字符会被转换为outchars中的第一个字符,第二个字符会被转换成outchars中的第二个字符。这个映射过程会一直持续到处理完指定字符。如果inchars和outchars的长度不同,则sed编辑器会产生一条错误消息。
这里有个使用转换命令的简单例子。

[root@kittod ~]# cat data5.txt 
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 1 again.
This is text you want to keep.
This is the last line in the file.
[root@kittod ~]# sed 'y/123/789/' data5.txt
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 4.
This is line number 7 again.
This is text you want to keep.
This is the last line in the file.

如你在输出中看到的, inchars模式中指定字符的每个实例都会被替换成outchars模式中相同位置的那个字符。

转换命令是一个全局命令,也就是说,它会将文本行中找到的所有指定字符自动进行转换,而不会考虑它们出现的位置。

[root@kittod ~]# echo "This 1 is a test of 1 try." | sed 'y/123/456/'
This 4 is a test of 4 try.

sed编辑器转换了在文本行中匹配到的字符1的两个实例。你无法限定只转换在特定地方出现的字符。

八、打印行

除了使用p标记和替换命令显示sed编辑器修改过的行。另外有3个命令也能用来打印数据流中的信息:

  • p命令用来打印文本行;
  • 等号( =)命令用来打印行号;
  • l(小写的L)命令用来列出行。

1、打印行

跟替换命令中的p标记类似, p命令可以打印sed编辑器输出中的一行。如果只用这个命令,也没什么特别的。

[root@kittod ~]# echo "this is a test" | sed 'p'
this is a test
this is a test

它所做的就是打印已有的数据文本。打印命令最常见的用法是打印包含匹配文本模式的行。

[root@kittod ~]# cat data4.txt 
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
[root@kittod ~]# sed -n '/number 3/p' data4.txt 
This is line number 3.

在命令行上用-n选项,你可以禁止输出其他行,只打印包含匹配文本模式的行。也可以用它来快速打印数据流中的某些行。

[root@kittod ~]# sed -n '2,3p' data4.txt 
This is line number 2.
This is line number 3.

如果需要在修改之前查看行,也可以使用打印命令,比如与替换或修改命令一起使用。可以创建一个脚本在修改行之前显示该行。

[root@kittod ~]# sed -n '/3/{
> p
> s/line/test/p
> }' data4.txt
This is line number 3.
This is test number 3.

sed编辑器命令会查找包含数字3的行,然后执行两条命令。首先,脚本用p命令来打印出原始行;然后它用s命令替换文本,并用p标记打印出替换结果。输出同时显示了原来的行文本和新的行文本。

2、打印行号

等号命令会打印行在数据流中的当前行号。行号由数据流中的换行符决定。每次数据流中出现一个换行符, sed编辑器会认为一行文本结束了。

[root@kittod ~]# cat data1.txt 
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
[root@kittod ~]# sed '=' data1.txt 
1
The quick brown fox jumps over the lazy dog.
2
The quick brown fox jumps over the lazy dog.
3
The quick brown fox jumps over the lazy dog.
4
The quick brown fox jumps over the lazy dog.
5
The quick brown fox jumps over the lazy dog.

ed编辑器在实际的文本行出现前打印了行号。如果你要在数据流中查找特定文本模式的话,等号命令用起来非常方便。

[root@kittod ~]# sed -n '/number 4/{
> =
> p
> }' data4.txt
4
This is line number 4.

利用-n选项,你就能让sed编辑器只显示包含匹配文本模式的行的行号和文本。

3、列出行

列出( list)命令( l)可以打印数据流中的文本和不可打印的ASCII字符。任何不可打印字符要么在其八进制值前加一个反斜线,要么使用标准C风格的命名法(用于常见的不可打印字符),比如\t,来代表制表符。

[root@kittod ~]# cat data6.txt 
This	line	contains	tabs.
[root@kittod ~]# sed -n 'l' data6.txt 
This\tline\tcontains\ttabs.$

制表符的位置使用\t来显示。行尾的美元符表示换行符。

九、使用 sed 处理文件

替换命令包含一些可以用于文件的标记。还有一些sed编辑器命令也可以实现同样的目标,不需要非得替换文本。

1、写入文件

w命令用来向文件写入行。该命令的格式如下:

[address]w filename

filename可以使用相对路径或绝对路径,但不管是哪种,运行sed编辑器的用户都必须有文件的写权限。地址可以是sed中支持的任意类型的寻址方式,例如单个行号、文本模式、行区间或文本模式。

下面的例子是将数据流中的前两行打印到一个文本文件中。

[root@kittod ~]# sed '1,2w test.txt' data4.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
[root@kittod ~]# cat test.txt 
This is line number 1.
This is line number 2.

当然,如果你不想让行显示到STDOUT上,你可以用sed命令的-n选项。
如果要根据一些公用的文本值从主文件中创建一份数据文件,比如下面的邮件列表中的,那么w命令会非常好用。

[root@kittod ~]# cat data7.txt 
Blum, R		Browncoat
BcGuiness, A	Alliance
Bresnahan, C	Browncoat
Harken, C	Alliance

[root@kittod ~]# sed -n '/Browncoat/w Browncoats.txt' data7.txt 
[root@kittod ~]# cat Browncoats.txt 
Blum, R		Browncoat
Bresnahan, C	Browncoat

sed编辑器会只将包含文本模式的数据行写入目标文件。

2、从文件读取数据

之前了解了如何在sed命令行上向数据流中插入或附加文本。读取( read)命令( r)允许你将一个独立文件中的数据插入到数据流中。
读取命令的格式如下:

[address]r filename

filename参数指定了数据文件的绝对路径或相对路径。你在读取命令中使用地址区间,只能指定单独一个行号或文本模式地址。 sed编辑器会将文件中的文本插入到指定地址后。

[root@kittod ~]# cat data8.txt 
This is an added line.
This is the second added line.

[root@kittod ~]# sed '3r data8.txt' data4.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is an added line.
This is the second added line.
This is line number 4.

sed编辑器会将数据文件中的所有文本行都插入到数据流中。同样的方法在使用文本模式地址时也适用。

[root@kittod ~]# sed '/number 2/r data8.txt' data4.txt
This is line number 1.
This is line number 2.
This is an added line.
This is the second added line.
This is line number 3.
This is line number 4.

如果你要在数据流的末尾添加文本,只需用美元符地址符就行了。

[root@kittod ~]# sed '$r data8.txt' data4.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is an added line.
This is the second added line.

读取命令的另一个很酷的用法是和删除命令配合使用:利用另一个文件中的数据来替换文件中的占位文本。举例来说,假定你有一份套用信件保存在文本文件中:

[root@kittod ~]# cat notice.std 
Would the following people:
LIST
please report to the ship's captain.

套用信件将通用占位文本LIST放在人物名单的位置。要在占位文本后插入名单,只需读取命令就行了。但这样的话,占位文本仍然会留在输出中。要删除占位文本的话,你可以用删除命令。结果如下:

[root@kittod ~]# sed '/LIST/{
r data7.txt
d
}' notice.std
Would the following people:
Blum, R		Browncoat
BcGuiness, A	Alliance
Bresnahan, C	Browncoat
Harken, C	Alliance
please report to the ship's captain.

现在占位文本已经被替换成了数据文件中的名单。

十、sed案例

1、把/etc/passwd 复制到/root/test.txt,用sed打印所有行;
[root@localhost ~]# sed -n '1,$w test.txt' /etc/passwd
[root@localhost ~]# sed -n p test.txt
2、打印test.txt的3到10行;
[root@localhost ~]# sed -n '3,10'p test.txt
3、打印test.txt 中包含’root’的行;
[root@localhost ~]# sed  -n '/root/p' test.txt
4、删除test.txt 的15行以及以后所有行;
[root@localhost ~]# sed -i '15,$d' test.txt(-i: 删除原文件内容)
[root@localhost ~]# sed -e '15,$d' test.txt(只会在命令行删除,不会真的删除原文件内容)等同于[root@localhost ~]# sed '15,$d' test.txt
5、删除test.txt中包含’bash’的行;
[root@localhost ~]# sed '/bash/'d test.txt
6、替换test.txt 中’root’为’toor’;
[root@localhost ~]# sed 's/root/toor/g' test.txt
7、替换test.txt中’/sbin/nologin’为’/bin/login’;
[root@localhost ~]# sed 's#/sbin/nologin#/bin/login#' test.txt
8、删除test.txt中5到10行中所有的数字;
[root@localhost ~]# sed '5,10s/[0-9]//g' test.txt
9、删除test.txt 中所有特殊字符(除了数字以及大小写字母);
[root@localhost ~]# sed 's/[^0-9a-zA-Z]//g' test.txt
10、在test.txt 20行到末行最前面加’aaa:’
[root@localhost ~]# sed '20,$s/^.*$/aaa:&/g' test.txt
11、复制/etc/grub2.cfg到/root/grub2.cfg,删除文件中所有以空白开头的行行首的空白字符;
[root@localhost ~]# sed -n '1,$w /root/grub2.cfg' /etc/grub2.cfg
[root@localhost ~]# sed 's/^[[:space:]]//' grub2.cfg
12、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
[root@localhost ~]# sed 's/^#[[:space:]]*//' /etc/fstab
13、给文件/root/anaconda-ks.cfg每一行行首增加#号
[root@localhost ~]# sed 's/^.*$/#&/' /root/anaconda-ks.cfg
14、在/etc/fstab文件中不以#开头的行的行首增加#号;
[root@localhost ~]# sed 's/^[^#]/#&/' /etc/fstab
15、处理/etc/sysconfig/network-scripts/路径,使用grep和sed命令取出其目录名和基名
[root@localhost ~]# echo "/etc/sysconfig/network-scripts/" |sed -r 's#^/(.*)/(.*)/#\1#'      etc/sysconfig
[root@localhost ~]# echo "/etc/sysconfig/network-scripts/" |sed -r 's#^/(.*)/(.*)/#\2#'
network-scripts
[root@localhost ~]# echo "/etc/httpd/conf.d/host.conf" | sed -r 's#(^/.*/)[^/].*#\1#'
/etc/httpd/conf.d/
[root@localhost ~]# echo "/etc/httpd/conf.d/host.conf" | sed -r 's#^/.*/([^/].*)#\1#'
host.conf
[root@localhost ~]# basename /etc/httpd/conf.d/host.conf
host.conf
[root@localhost ~]# dirname /etc/httpd/conf.d/host.conf
/etc/httpd/conf.d
[root@localhost ~]# echo "/etc/sysconfig/network-scripts/"|grep  -o -E "[^/]+/?$"|grep -o -E "^[^/]+"
network-scripts
[root@localhost ~]# echo "/etc/sysconfig/network-scripts/"|grep  -o -E "(^/([^/]+/)*[^[:space:]])|^/"|grep -o -E "^/([^/]+/)*"|grep -o -E "(/[^/]+)+|^/"
/etc/sysconfig
16、利用sed 取出ifconfig命令中本机的IPv4地址
[root@localhost ~]# ifconfig  |sed -n '2p' | sed -r "s/.*inet[[:space:]]*//" | sed -r "s/[[:space:]]*netmask.*//"
192.168.168.128
17、统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个字段的重复次数
[root@localhost ~]#  ls /mnt/Packages/|grep "rpm$"|sed -r 's@.*\.(.*)\.rpm@\1@'|sort|uniq -c    
   1085 i686
   1216 noarch
   2319 x86_64
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux---sed命令 的相关文章

随机推荐

  • (css)background-image设置背景图片大小

    css background image设置背景图片大小 效果 代码 middle li width 100 height 170px background image url assets images applyBj png backg
  • maven中打包项目为war包的pom.xml配置

    maven中打包成war包的pom xml配置 1 完整配置 这个是使用servlet的完整配置 其他的类似
  • Linux用普通用户输入命令报错-fork 资源不可用

    解决办法 修改最大限制打开文件数 vi etc security limits d 修改为65535 修改完之后重启应用服务器 系统正常访问
  • 服务器centos系统相关备注

    Install the UFW package using yum sudo yum y install ufw 开放端口 sudo ufw default allow outgoing sudo ufw allow 7000 tcp su
  • 解决Ubuntu16.04ping www.baidu.com不通的问题

    想要安装一个包 发现Ubuntu16 04不能上网 在终端ping百度 发现不通 问题如下 解决方法 1 检查你是否有IP信息 使用命令ifconfig 如果没有IP 则参照我的上一篇文章 获取IP 2 如果有IP 则进行下一步 执行以下命
  • 其他总结(四)--win10手动一小时四小时一天重新打开wifi

    win10出现这种个情况 是因为你吧笔记本的wifi关了 可以按fn F 这里的 号指你笔记本上的含有wifi信号开关的那个F键 我的是F2 重新开启就可以连接了 还可以用其他方式打开 https jingyan baidu com alb
  • Python语言—爬虫之旅

    活动地址 毕业季 进击的技术er 一 目前是大几 学习的专业是 本专业让你Get到哪些新技能 二 从哪个瞬间开始让你决定学习编程语言 三 进入大学敲下的第一行代码是什么 四 目前学习中最大的收获难是 五 大学期间的学习目标是 对未来的职业规
  • 使用pandas对xlsx文件的基本操作

    起因 因最近实习期间 要求查看 xlsx文件中数据是否有误 由于数据较多 想用python去执行 结果发现网上对xlsx文件操作或是太旧 大多难以应用 所以自己整理了一下 以备自己后用 模拟一个测试数据集data test xlsx文件 文
  • Broken pipe异常分析和常用锁的命令

    错误描述 ClientAbortException java io IOException Broken pipe 这种就是获取不到连接了 连接已经断开了 出现这种问题的可能性 1 连接太多 到了最大连接数 每个连接处理的速度太慢 而导致处
  • COLMAP导出相机外参(bin文件转txt文件)

    官方给出的images txt如下图 Image list with two lines of data per image 每张图像数据占两行 IMAGE ID QW QX QY QZ TX TY TZ CAMERA ID NAME 图像
  • 基于mykernel完成多进程的简单内核

    学号 476 实验资源 https github com mengning linuxkernel 1 实验环境准备 使用个人电脑的parallels desktop ubuntu虚拟机 1 安装qemu sudo apt get inst
  • DCT变换 / DWT变换 ----课堂笔记

    之前也学过 但没有个具体总结 忘差不多了 DCT变换 一 DCT变换的全称是离散余弦变换 DCT 主要用于数据或者图像的压缩 由于DCT能够将空域的信号转换到频域上 因此具有良好的去相关性的性能 DCT变换本身是无损的且具有对称性 对原始图
  • 分支创建&查看&切换

    1 初始化git目录 创建文件并将其推送到本地库 git init echo 123 gt hello txt git add hello txt git commit m first commit hello txt git init I
  • hive分区与分桶

    为什么要分桶 获得更高的查询处理效率 在分区数量过于庞大以至于可能导致文件系统崩溃时 或数据集找不到合理的分区字段时 我们就需要使用分桶来解决问题了 分区中的数据可以被进一步拆分成桶 不同于分区对列直接进行拆分 桶往往使用列的哈希值对数据打
  • 什么是模式识别(简单易懂)

    1 大脑有一种偏好 叫模式化 这也是源于大脑具有的一个重要功能 模式识别 大脑不是把每个信息点全部处理后再进行识别 而是迅速抓住几个重要特征 然后与大脑中的已有模式对比 只要差不多 就套用 比如 我们可以在一张很多人的合影中迅速识别出某个特
  • 解决开启防火墙后,服务器不能ping通,网站不能访问的问题

    1 解决能ping通的设置 控制面板 Windows防火墙 高级设置 入站规则 然后右键启用这个选项就可以了 2 解决网站不能访问的设置 控制面板 Windows防火墙 高级设置 点击入站规则 新建规则 这样就将80端口加入到入站规则中 实
  • CPU与GPU上检测pytorch是否安装成功

    文章目录 python学习 0 安装pytorch 1 验证pytorch已经安装成功 1 1确定pytorch版本 1 2 测试pytorch基础功能 1 3 在GPU上测试pytorch 1 4使用实例代码测试 python学习 pyt
  • 历史与AES算法

    AES算法早期体现 应该追溯到明朝科举制时期 当然 这种算法不是用来答题的 而是用来作弊的 假如 张三是明朝某大户人家的公子哥 他除了以后要继承遗产外 还要考虑一个光宗耀祖的问题 但在古代 解决这个问题的唯一办法就是通过科举 可张三天生喜欢
  • VM ubuntu所在的移动硬盘意外接触不良,虚拟机异常退出后无法重启

    我的VM版本为VMware Workstation 17 Pro Ubuntu版本为22 04 一次因为虚拟机所在的移动硬盘接触不良 异常退出 重启主机后启动虚拟机 先是ubuntu ubuntu高级选项等选项让我选 然后在我选择了ubun
  • linux---sed命令

    sed命令目录 一 sed命令概念 二 sed命令的格式 1 在命令行定义编辑器命令 2 在命令行使用多个编辑器命令 3 从文件中读取编辑器命令 三 更多的替换选项 1 替换标记 有4种可用的替换标记 2 替换字符 四 使用地址 在sed编