首页 > 系统相关 >Linux三大剑客之sed

Linux三大剑客之sed

时间:2024-01-14 11:06:07浏览次数:28  
标签:input sed GeekDevOps Linux world txt hello 三大


一、简介

sed英文全称是stream editor。由贝尔实验室开发,如今主流Unix/Linux操作系统上都集成了这个工具。sed由自由软件基金组织(FSF)开发和维护,并且随着GNU/Linux进行分发,通常它也称作 GNU sed。本文将按照GUN官方在线手册的内容对sed进行介绍。

二、获取帮助信息
[sed@GeekDevOps ~]$ sed --help
[sed@GeekDevOps ~]$ man sed

我们可以通过以上2种方式获取关于sed的帮助信息,也可以通过GUN网站sed在线帮助页面获取更加详细的帮助信息(https://www.gnu.org/software/sed/manual/sed.html

三、sed的使用
3.1 综述

sed遵循简单的工作流:读取(从输入中读取某一行),执行(在某一行上执行sed命令)和显示(把结果显示在输出中)。通常sed命令这样被调用:

sed SCRIPT INPUTFILE...

例如,把文件input.txt中出现的“hello”全部替换为“world”并输出到文件output.txt中:

[sed@GeekDevOps ~]$ echo "hello world">input.txt
[sed@GeekDevOps ~]$ sed "s/hello/world/" input.txt >output.txt
[sed@GeekDevOps ~]$ cat output.txt 
world world

如果你没有指定输入文件或输入文件是“-”,sed获取到是是标准出入流的内容,以下命令是等价的:

sed 's/hello/world/' input.txt > output.txt
sed 's/hello/world/' < input.txt > output.txt
cat input.txt | sed 's/hello/world/' - > output.txt

sed把输出写到标准输出中,使用选项-i可以编辑原文件并将替换结果打印到标准输出。把输出写入到其他文件中我们也可以参阅W和s///w命令。以下命令修改了文件且不产生任何输出。

[sed@GeekDevOps ~]$ sed -i "s/hello/world/" input.txt 
[sed@GeekDevOps ~]$ cat input.txt 
world world

默认情况下sed打印所有处理过的输出(除非输入已经被诸如d之类的命令修改或删除)。使用选项-n可以不输出除指定内容之外的打印,使用p命令可以打印指定行。以下命令将只打印输入文件的第5行:

[sed@GeekDevOps ~]$ sed -n "5p" /etc/passwd
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sed以一个长流的方式处理多个输入文件。以下例子只打印第一个文件的第一行及最后一个文件的最后一行,其实也可以理解成sed把三个文件当做一个文件来处理了,依次追加到第一个文件的后面。也可以用选项-s来逆转这种操作,即把每个文件分开来处理。

[sed@GeekDevOps ~]$ sed -n '2p;$p' /etc/selinux/config /etc/aliases /etc/passwd
# This file controls the state of SELinux on the system.
sed:x:1000:1000::/home/sed:/bin/bash
[sed@GeekDevOps ~]$ sed -ns '2p;$p' /etc/selinux/config /etc/aliases /etc/passwd
# This file controls the state of SELinux on the system.
SELINUXTYPE=targeted 
#  Aliases in this file will NOT be expanded in the header from
#root:      marc
bin:x:1:1:bin:/bin:/sbin/nologin
sed:x:1000:1000::/home/sed:/bin/bash

sed -n -s 与sed -ns这两种写法在本质上是一样的。
不加选项-e(脚本,–expression=脚本)或-f(–file,脚本文件),sed使用第一个非选项参数作为脚本,下面的例子中就是以非选项参数作为输入文件。如果选项-e或-f 被用于指定脚本,那么所有的非选项参数被当作输入文件。选项-e和-f可以联合使用,能出现多次(所有的单个的脚本将被连接起来成为最终有效的实例)。

[sed@GeekDevOps ~]$ echo "hello world">input.txt 
[sed@GeekDevOps ~]$ sed 's/hello/world/' input.txt >output.txt
[sed@GeekDevOps ~]$ cat output.txt 
world world
[sed@GeekDevOps ~]$ sed -e 's/hello/world/' input.txt >output.txt
[sed@GeekDevOps ~]$ sed --expression='s/hello/world/' input.txt > output.txt
[sed@GeekDevOps ~]$ cat output.txt 
world world
[sed@GeekDevOps ~]$ echo 's/hello/world/' > myscript.sed
[sed@GeekDevOps ~]$ cat myscript.sed 
s/hello/world/
[sed@GeekDevOps ~]$ sed -f myscript.sed input.txt >output.txt 
[sed@GeekDevOps ~]$ cat output.txt 
world world
[sed@GeekDevOps ~]$ sed --file=myscript.sed input.txt > output.txt
[sed@GeekDevOps ~]$ cat output.txt 
world world
3.2 命令行选项

完整格式调用sed:

sed OPTIONS... [SCRIPT] [INPUTFILE...]

sed可能被以下命令行选项调用:
–version:打印版本信息。

–help:打印简要帮助信息并退出。

-n、–quiet、–silent:只输出明确处理过的内容。

-e script 、–expression=script:指定脚本。

-f script-file、–file=script-file:指定脚本文件。

-i[SUFFIX]、–in-place[=SUFFIX]:在原文件上修改并取代原文件。这一选项暗含-s。

-l N、–line-length=N:指定“l”命令的换行期望长度。长度为0则意味着不含长换行。如果不指定,则换行长度为70。

–posix:GUN sed包含了几个扩展POSIX sed。为了简化书写这些便携脚本,这个选项禁用了这个手册所有的扩展以及附加命令。扩展中被POSIX执行的外部语法大部分接受sed程序,但是以上这些中的一些(例如在报告bug中的N命令描述的行为)事实上违反了标准。如果你需要禁用后期的扩展,你可以设置POSIXLY_CORRECT 变量为以非空值。

-b、–binary:这个选项在每个平台都是可用的,仅仅在操作系统中区分文本文件与二进制文件起到作用。

–follow-symlinks:这个选项仅在支持符号连接且对选项-i被指定有影响的情况下可用。在这种情况下,如果被指定文件在命令行中是一个符号连接,sed将跟随连接并编辑连接的最终目标文件。默认行为是中断符号连接,因此连接目标将不被修改。

-E、-r:扩展正则表达式。

-s、–separate:在上文中已经举过例子,当处理多个输入文件,一般会被合并成一个文件来处理。使用这个选项则可以让sed把各个文件分开单独处理。

–sandbox:沙盒,在沙盒模式,e/w/r命令被拒绝-如果程序包含它们则还没运行时它们将丢弃。沙盒模式确保了sed在输入文件上的操作运行在指定的命令行上,而不能运行在外部命令上。

-u、–unbuffered:从输入文件读取最少的数据,更频繁的刷新输出。这将特别有用,特别像在tail -f这种情况下,能够让我们尽快地看出输出结果。

-z、–null-data、–zero-terminated:把输出看作一个一个被0字节(如:ASCII中的“NULL”)的中断符代替换行的集合。这个选项常和“sort -z”和“find -print0”一起使用。

3.3退出状态

0:成功结束。
1:无效命令、无效语法、无效正则表达式、无效的带–posix的sed扩展命令
2:一个或多个被指定的输入文件不能在命令行中被打开。
4:I/O错误或运行时一个严重进程错误,GUN sed 被立即终止。

四、sed脚本
4.1 sed脚本综述

sed命令遵循以下语法:
[addr]X[options]
X是一个单个字母sed命令。[addr]是一个可选的行地址。如果[addr]是被指定的,那么命令X在匹配的行将被执行。[addr]可以使用一个单独的行号、正则表达式、或行的范围。附加[options]被用于一些sed命令。
以下例子删除了GeekDevOps.txt的第3到5行,3,5是一个地址范围,d是删除命令:

[sed@GeekDevOps ~]$ sed "3,5d" GeekDevOps.txt >GeekDevOps.txt.new
[sed@GeekDevOps ~]$ diff GeekDevOps.txt GeekDevOps.txt.new
3,5d2
<         user_input = raw_input("Enter a positive integer to guess: ")
<         if len(user_input)==0 or not user_input.isdigit():
<             print "Not a positive integer!"

以下例子将打印所有以”def”开头的行后退出,退出代码为42,如果没有查找到或者遇到其他错误,退出状态代码将为0(为了节约篇幅,不举例),/^def是一个正则表达式地址,q是退出命令,42是命令选项:

[sed@GeekDevOps ~]$ sed "/^def/q42" GeekDevOps.txt
def guess_my_number(n):
[sed@GeekDevOps ~]$ echo $?
42

多个脚本或脚本文件可以使用选项-e或-f分别指定,如不分别指定的话应该以分号。

[sed@GeekDevOps ~]$ sed -e 's/while/do/;/^def/d' GeekDevOps.txt>GeekDevOps.txt.new
[sed@GeekDevOps ~]$ cat GeekDevOps.txt.new
    do True:
        user_input = raw_input("Enter a positive integer to guess: ")
    ...
[sed@GeekDevOps ~]$ sed -e "s/while/for/" -e '/^def/d' GeekDevOps.txt>GeekDevOps.txt.new
[sed@GeekDevOps ~]$ cat GeekDevOps.txt.new
    for True:
...
[sed@GeekDevOps ~]$ echo "s/while/do_for/">test.sed
[sed@GeekDevOps ~]$ sed -f test.sed -e '/^def/d' GeekDevOps.txt>GeekDevOps.txt.new
[sed@GeekDevOps ~]$ cat GeekDevOps.txt.new
    do_for True:
...

命令a,c,i由于他们的语法原因,不能以分号作为命令分隔符。

4.2 sed命令概述

以下命令在GUN sed是被支持的。一些是标准的POSIX命令,其他的是GUN扩展命令。(此部分原文内容较多,不一一介绍,截取常用部分进行介绍)

a\

文本

在一行后面追加文本。

a 文本

在一行后面追加文本(选择性语法)。

b label

分支无条件标签。在下一个循环开始时可能被省略。

c\
文本

在原位置替换。

c 文本

在原位置替换(选择性语法)。

d

删除模式空间,立即开始下一循环。

i\

文本

在某行之前插入。

i 文本

在某行之前插入(选择性语法)。

q[exit-code]

没有任何需要处理的命令或输出退出sed。
(quit) Exit sed without processing any more commands or input.

Q[exit-code]

类似于q,但是不打印模式空间的内容。具体我们看一下以下例子:
[sed@GeekDevOps ~]$ sed -e '/^def/q23' GeekDevOps.txt
def
[sed@GeekDevOps ~]$ echo $?
23
[sed@GeekDevOps ~]$ sed -e '/^def/Q23' GeekDevOps.txt
[sed@GeekDevOps ~]$ echo $?
23

退出代码都一样,区别就是q有打印输出,Q没有输出。

五、用法举例
5.1
[sed@GeekDevOps ~]$ seq 6|sed '1d
> 2d
> 5d'
3
4
6

等价于:

[sed@GeekDevOps ~]$ seq 6|sed '1d;3d;5d;'
2
4
6

在命令行中,所有的sed命令通过换行来指定,也可以通过分号来指定。

5.2
[sed@GeekDevOps ~]$ seq 4 | sed '{1d;3d}'
2
4
[sed@GeekDevOps ~]$ seq 6|sed '{1d;3d};5d'
2
4
6
[sed@GeekDevOps ~]$ seq 6|sed '{1,3d};5d'
4
6

命令{},b,t,T,: 等是可以被分号隔开的。

5.3

替换指定行的内容。以下例子将在第5行中把hired替换成success:

[sed@GeekDevOps ~]$ sed '5s/hired/success/' GeekDevOps.txt | nl
     1  My father was a self-taught mandolin player. He was one of the best string instrument players in our town. He could not read
     2  music, but if he heard a tune a few times, he could play it. When he was younger, he was a member of a small country music band.
     3  They would play at local dances and on a few occasions would play for the local radio station. He often told us how he had
     4  auditioned and earned a position in a band that featured Patsy Cline as their lead singer. He told the family that after he was
     5  success he never went back.

以下例子中,把包含music的行中的play替换成enjoy。

[sed@GeekDevOps ~]$ sed '/music/s/play/enjoy/' GeekDevOps.txt |nl
     1  My father was a self-taught mandolin player. He was one of the best string instrument players in our town. He could not read
     2  music, but if he heard a tune a few times, he could enjoy it. When he was younger, he was a member of a small country music band.
     3  They would play at local dances and on a few occasions would play for the local radio station. He often told us how he had

以下例子中,把1-3行中的he全部替换成one,如果后面不加g,则只替换第一个匹配的。

[sed@GeekDevOps ~]$ sed "1,3s/he/one/g" GeekDevOps.txt
My fatoner was a self-taught mandolin player. He was one of tone best string instrument players in our town. He could not read
music, but if one oneard a tune a few times, one could play it. Wonen one was younger, one was a member of a small country music band.
Toney would play at local dances and on a few occasions would play for tone local radio station.

不含指定部分才进行匹配替换。以下例子中把不含单词apple的行中的hello替换成Hello,感叹号“!”取反,指定行的范围也是一样的操作。

[sed@GeekDevOps ~]$ sed '/apple/!s/hello/Hello/' test.txt
Hello world!This is my apple.Don't touch it.
hello world!This is my apple.Don't touch it.
Hello world!This is my food.Don't touch it.
5.4

sed也是支持正则表达式的。以下例子匹配了/etc/passwd文件中以bash结尾的行。

[sed@GeekDevOps ~]$ sed -n '/bash$/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sed:x:1000:1000::/home/sed:/bin/bash

以下三种写法都是等价的,只是分隔符不一样而已,如果正则表达式或分隔符本身就包含斜杠的话,那么是需要进行转义处理的。

[sed@GeekDevOps ~]$ sed -n '/^\/home\/GeekDevOps/p' test.txt
/home/GeekDevOps
[sed@GeekDevOps ~]$ sed -n '\;^/home/GeekDevOps;p' test.txt
/home/GeekDevOps
[sed@GeekDevOps ~]$ sed -n '\%^/home/GeekDevOps%p' test.txt
/home/GeekDevOps

地址也可以用范围来表示,例如:

[sed@GeekDevOps ~]$ nl test.txt |sed -n '2,+1p'
2  hello world!This is my apple.Don't touch it.
3  hello world!This is my food.Don't touch it.

接下来再看一个扩展正则表达式的例子。本例中匹配到的是标准输出流中的单词,把每个单词中的字符全部替换成X。如果表达式中的X换成XY的话,那么会将标准输出流中的每个字符换成XY。

[sed@GeekDevOps ~]$ echo 'GeekDevOps is a very useful media !' |sed 's/\w/X/g'
XXXXXXXXXX XX X XXXX XXXXXX XXXXX !

下面的例子中,会在每个单词的前面添加一个“#”,如果需要在每个单词的后面添加内容,那么表达式应为:\>

[sed@GeekDevOps ~]$ echo 'GeekDevOps is a very useful media !' |sed 's/\</#/g'
#GeekDevOps #is #a #very #useful #media !
[sed@GeekDevOps ~]$ echo 'GeekDevOps is a very useful media !' |sed 's/\</\#/g'
#GeekDevOps #is #a #very #useful #media !

关于sed的介绍就到此为止吧,!写了许多,感觉自己都搞得晕乎乎的,掌握以上内容一般的文档处理应该是没有问题了!


标签:input,sed,GeekDevOps,Linux,world,txt,hello,三大
From: https://blog.51cto.com/ivandu/9238982

相关文章

  • 利用Linux命令高效查找大文件为windows系统瘦身
    Windows系统是大家平时使用得比较多的办公桌面系统,但是,作为一名运维工程师,Linux命令行才是我的首选。最近在折腾Git这款很强大的工具。在瞎折腾的过程中发现一个比较好用的功能:一条Linux命令,找出你系统中的大文件。在此跟大家分享一下。第一步:安装Git考虑到一些平台不支持发链接,在......
  • Linux通配符的使用详解
    一、简介一般生产环境的服务器默认都是不安装图形化界面的,习惯了在命令行环境下工作是,大家会发现:命令行操作效率比图形化界面效率高很多。由命令行环境中,我们不能直观地看到一些文件或目录的名称及其他一些信息,这时候通配符就派上用场啦!当不知道真正字符或懒得输入完整文件或目录名......
  • Linux三剑客之grep
    一、概述grep(globalsearchregularexpression(RE)andprintouttheline,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。这也是一个我们比较常用的命令之一,好多时候虽然没通过系统的学习,但是我们还是会经常用到......
  • 一个简单的Linux系统加固方案
    一、系统默认帐号及组管理删除系统默认不使用的帐号,包括:lp、mail、games、ftp、nobody、postfix等。删除系统默认不使用的组,包括:mail、games、ftp、nobody、postfix等。二、启用密码策略1.密码60天过期,修改密码最小间隔为1天,最短密码要求8位,在密码过期前7天内通知用户。通过修改/e......
  • Linux中find命令的使用详解(上)
    find命令是各种Linux发现版中比较重要的、常用的一个命令,该命令功能强大,熟练掌握了这个命令的使用,对平时的系统运维、管理工作会起到事半功倍的效果。一.获取帮助信息[root@root@GeekDevOps-find~]#find--help[root@root@GeekDevOps-find~]#manfind大家会发现帮助信息很多,但......
  • 两种方法实现Linux不活动用户登录超时后自动登出
    在平常的工作中,windows系统使用的比较多一些,身边的很多同事都会对自己的电脑进行一些个性化设置,比如离开一段时间后自动锁屏、自动关闭屏幕、自动注销当前登录等。在windows下可以这样操作,那么在Linux下是否也可以这样操作呢?经过一段时间的摸索,本人发现了2中方法来实现Linux下不活......
  • 浅谈Linux下傻瓜式磁盘分区工具cfdisk的使用
    对于新手来说,Linux环境下的磁盘分区可能还会存在一些困难。对于熟悉Linux的朋友来说,我们还有fdisk、parted(2TB以上的磁盘分区使用)等磁盘分区工具可以使用。在我们新增磁盘或者在原来磁盘上进行扩容时就会使用到磁盘分区工具,磁盘分区对于整个系统的管理十分重要。1.增加一块容量......
  • 再议Linux中一些发行版中默认下载或上传工具curl的使用
    在目前的CentOS最小化安装发行版中,系统默认的下载/上传工具为:curl。curl支持包括HTTP、HTTPS、ftp等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。我们先来大概看一下curl工具的各选项的大概含义。-a/–append......
  • RockyLinux安装QEMU/KVM虚拟化
    一、QEMU/KVM技术简介QEMU/KVM是一种开源虚拟化技术,全称是QuickEmulator/KernelBasedVirtualMachine。它结合了QEMU的模拟器和KVM(内核虚拟机)的加速器,提供了基于硬件的全虚拟化和容器级的系统虚拟化能力。QEMU是一个用于模拟计算机硬件的开源软件,它可以模拟各种硬件设备,包括CP......
  • spark 3.x idea linux远程开发环境搭建
    依赖包jdk8或11都行,不要到jdk17jdk17第一个问题是jdk内部类默认不允许反射,很多配置要改。scala2.13scala2.13版本是为scala3.0版本准备的,改进挺多。可通过scala编程(第四版)学习。hadoop3.2.1因为windowshadoopwinutils当前最新仅仅到3.2.1,所以最好是相......