热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Sed命令详解及应用实例

第一部分:Sed基本用法sed是非交互式的编辑器。它不会修改文件,除非使用shell重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。sed编辑器逐行处理文件(或输入),并将结果发送到屏

第一部分:Sed基本用法

sed是非交互式的编辑器。它不会修改文件,除非使用shell重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。

sed编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed便结束运行。sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。下面先来预览下sed的常用命令及参数。

1. p命令.

p命令用于输出匹配行的内容,比如test.txt文件的内容如下,后续说明均已此文件内容来加以说明

viidiot@ubuntu:~/Desktop$ cat test.txt

line one

line two

Hi,everybody,i'm linux-code!

   Linux-code,to be the best one!


单纯的p命令会输出如下,即含有Hi的行被输出了两次。

viidiot@ubuntu:~/Desktop$ sed '/Hi/p' test.txt

line one

line two

Hi,everybody,i'm linux-code!

Hi,everybody,i'm linux-code!

   Linux-code,to be the best one!


如果在p命令的基础上,加上-n选项,可以输出含有特定模式的行,如下命令则输出test.txt文件中含有模式Hi的行。

viidiot@ubuntu:~/Desktop$ sed -n '/Hi/p' test.txt

Hi,everybody,i'm linux-code!

2. d命令

d命令用于删除特定行。

比如要删除test.txt中第一二行,其命令如下:

viidiot@ubuntu:~/Desktop$ sed '1,2d' test.txt

Hi,everybody,i'm linux-code!

   Linux-code,to be the best one!


若要删除最后一行,命令如下:

viidiot@ubuntu:~/Desktop$ sed '$d' test.txt

line one

line two

Hi,everybody,i'm linux-code!


同理,删除含有linux-code的行:

viidiot@ubuntu:~/Desktop$ sed '/linux-code/d' test.txt

line one

line two

   Linux-code,to be the best one!


3. S命令

s命令用于文本替换。

比如,要将test.txt文件中的Linux-code替换成Viidiot

viidiot@ubuntu:~/Desktop$ sed 's/Linux-code/Viidiot/g' test.txt

line one

line two

Hi,everybody,i'm linux-code!

   Viidiot,to be the best one!

注意后面那个g参数。g表示多次匹配,如果不加g参数,若某一行有多个匹配在字符串,只替换掉第一次匹配的。


替换以line开头的行第一个单词替换为linux-code

viidiot@ubuntu:~/Desktop$ sed 's/^line/linux-code/' test.txt

linux-code one

linux-code two

   Hi,everybody,i'm linux-code!linux-code!

   Linux-code,to be the best one!


替换以line开头的行最后一个单词替换为linux-code

viidiot@ubuntu:~/Desktop$ sed 's/one$/linux-code/' test.txt

line linux-code

line two

   Hi,everybody,i'm linux-code!linux-code!

   Linux-code,to be the best one!


如果需要将以line开头的行全部替换掉,而不是仅仅替换掉一个单词怎么做呢?后面接.*表示通配的意思,也即^line.*表示以line开头,后接0个或多个任意字符。

viidiot@ubuntu:~/Desktop$ sed 's/^line.*/linux-code/' test.txt

linux-code

linux-code

   Hi,everybody,i'm linux-code!linux-code!

   Linux-code,to be the best one!


4. e选项

-e即edit的意思,编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。

viidiot@ubuntu:~/Desktop$ sed -e '1,2d' -e 's/linux-code/Linux/' test.txt

   Hi,everybody,i'm Linux!linux-code!

   Linux-code,to be the best one!

上述为sed命令使用选项-e进行多重编辑后得到的结果。第一重编辑删除第1、2行。第二重编辑将出第1、2行外的所有linux-code替换为Linux。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。


5. r命令

r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上。

viidiot@ubuntu:~/Desktop$ sed '/linux-code/r test1.txt' test.txt

line one

line two

   Hi,everybody,i'm linux-code!linux-code!

linux-code

be perfect!

   Linux-code,to be the best one!

上述命令的意思是:如果在文件test.txt的某一行匹配到模式linux-code,就在该行后读入文件test1.txt的内容。如果包含linux-code的行不止一行,则在出现linux-code的各行后都读入test1.txt文件的内容。


6. w命令

viidiot@ubuntu:~/Desktop$ sed '/code/w test1.txt' test.txt

上述命令将test.txt文件中包含模式code的行内容写入到test1.txt。

7. a\命令

a\命令将添加新文本到文件中当前行(即读入模式缓冲区中的行)的后面。所追加的文本行位于sed命令的下方另起一行。如果要追加的内容超过一行,则每一行都必须以反斜线结束,最后一行除外。最后一行将以引号和文件名结束。

viidiot@ubuntu:~/Desktop$ cat test1.txt

   Hi,everybody,i'm linux-code!linux-code!

   Linux-code,to be the best one!

通过a\命令将含有模式everybody的行后面加入一行:why ?

viidiot@ubuntu:~/Desktop$ sed '/everybody/a\ why ?' test1.txt

   Hi,everybody,i'm linux-code!linux-code!

why ?

   Linux-code,to be the best one!


8.i\命令

i\命令与a\命令相反,它是在匹配行的前面插入一行。

viidiot@ubuntu:~/Desktop$ sed '/everybody/i\ you are beautiful' test1.txt

you are beautiful

   Hi,everybody,i'm linux-code!linux-code!

   Linux-code,to be the best one!


9. c\命令

c\命令将匹配行修改成我们设定的内容。如下则将test1.txt中含有everybody的行修改为you are beautiful

viidiot@ubuntu:~/Desktop$ sed '/everybody/c\ you are beautiful' test1.txt

you are beautiful

   Linux-code,to be the best one!

10. y命令

y命令与UNIX/Linux中的tr命令类似,字符按照一对一的方式从左到右进行转换。例如,y/abc/ABC/将把所有小写的a转换成A,小写的b转换成B,小写的c转换成C。

viidiot@ubuntu:~/Desktop$ sed 'y/code/CODE/' test1.txt

   Hi,EvErybODy,i'm linux-CODE!linux-CODE!

   Linux-CODE,tO bE thE bEst OnE!

将对应小写字母全部替换成其大写字母。


第二部分:Sed脚本

通过编写脚本我们可以方便的批量执行命令。sed脚本就是写在文件中的一系列sed命令。sed脚本中,要求命令的末尾不能有任何多余的空格或文本。如果在一行中有多个命令,要用分号分隔。执行脚本 时,sed先将输入文件中第一行复制到模式缓冲区,然后对其执行脚本中所有的命令。每一行处理完毕后,sed再复制文件中下一行到模式缓冲区,对其执行脚 本中所有命令。使用sed脚本时,不再用引号来确保sed命令不被shell解释。

举例:我们现在来完成如下任务

在test1.txt中的开头插入一行欢迎词:Welcome to linux-code

在末尾加入一行:good bye!

将文章中所有code替换成CODE。

那么我们可以编写一个名为sedscript脚本,脚本具体内容如下:

viidiot@ubuntu:~/Desktop$ cat sedscript

1i\Welcome to linux-code

s/code/CODE/g

$a\goodbye!

然后再将sed脚本应用到test1.txt文件上

viidiot@ubuntu:~/Desktop$ sed -f sedscript test1.txt

Welcome to linux-code

   Hi,everybody,i'm linux-CODE!linux-CODE!

   Linux-CODE,to be the best one!

goodbye!

第三部分:练习题

学习了sed的基本知识,现在我们来检验下成果吧!呵呵。。。

1、Sed中如何替换多行中的有规律的数字字符串 

输入:

hello world balabala - . gene_id "240838 "; transcript_id "240838";

hello world balabala again - . gene_id "240838 "; transcript_id "240838";

balaba….

输出:

hello world balabala - . gene_id "zgg240838 "; transcript_id "zgg240838";

hello world balabala again - . gene_id "zgg240838 "; transcript_id "zgg240838";

balaba…

也即,将字符gene_id“后接数字以及transcript_id "后接数字中的引号与数字之间插入zgg字符串。

脚本编写:

 sed  's/gene_id "\([0-9]\+\)"; transcript_id "\([0-9]\+\)";/gene_id "zgg\1"; transcript_id "zgg\2";/g' test.txt

注:1. 数字的匹配[0-9]

2.[0-9]后接\+表示匹配一个或多个数字

3.匹配部分加括号,引用匹配部分用\1,\2,....等等。

4.sed执行多个匹配用分号连接,整个命令用’’引在内部。

2、在文本中每一行添加行头行尾

比如test.txt 内容如下所示:

viidiot@ubuntu:~/Desktop$ cat test.txt

line one

line two

line three

line four

1)在每行文字开头添加文字“Viidiot ”:

viidiot@ubuntu:~/Desktop$ sed '/./s/^/Viidiot /g' test.txt

Viidiot line one

Viidiot line two

Viidiot line three

Viidiot line four

2)末尾添加文字“ Viidiot”:

viidiot@ubuntu:~/Desktop$ sed '/./s/$/ Viidiot/g' test.txt

line one Viidiot

line two Viidiot

line three Viidiot

line four Viidiot

3、利用sed进行格式转换

比如需要将text.txt中如下内容

   dn: uid=admin,ou=ITaccounts,dc=tc
   uid: admin
   cn: admin cn
   sn: admin sn


   dn: uid=0037,ou=employees,dc=tci
   uid: 0037
   cn: thinker
   sn: zzz


转换成xml格式如下:
  
   uid=admin,ou=ITaccounts,dc=tc
     admin
     admin cn
   admin sn
  

  
   uid=0037,ou=employees,dc=tci
     0037
     thinker
     zzz
    


则可以定义下面的sedscript文件:
/^dn:[[:space:]]/i\

s/^dn:[[:space:]]\(.*\)$/\1<\/dn>/g
s/^uid:[[:space:]]\(.*\)$/\1<\/uid>/g
s/^cn:[[:space:]]\(.*\)$/\1<\/cn>/g
s/^sn:[[:space:]]\(.*\)$/\1<\/sn>/g
s/^$/<\/entity>/g
第一行和第二行实现的功能就是在每个dn:开头的行前面加上一行。最后一行是碰到空行补上这 个结束标记。

另外,在执行替换的时候可以通过使用\(\)把被替换的字符串分组,在替换的部分里面用\1、\2这种方式引用被替换文字里面的相应的组。

用这种方法把ldif文件里面[:]前的东西删掉并且在两边增加相应的xml标记。
仔细想想,4行替换也许用下面的1行就能实现?
s/^\(.*\):[[:space:]]\(.*\)$/<\1>\2<\/\1>/g

viidiot@ubuntu:~/Desktop$ sed -f sedscript test.txt

uid=admin,ou=ITaccounts,dc=tc

admin

admin cn

admin sn

uid=0037,ou=employees,dc=tci

0037

thinker

zzz


4、在匹配的行前面插入一行

viidiot@ubuntu:~/Desktop$ cat test.txt

line one

line two

Hi,everybody,i'm linux-code!

   Linux-code,to be the best one!

将以空格开头的行前面插入一行文字:a new paragraph

viidiot@ubuntu:~/Desktop$ sed '/^[[:space:]]/i   a new paragraph'  test.txt

line one

line two

a new paragraph

Hi,everybody,i'm linux-code!

a new paragraph

   Linux-code,to be the best one!


5、在文章中每一行前加上行号

此题是由sed引入的题外话。用sed怎么去完成?读者自己开动开动脑筋吧!

在文章中每一行加上行号的方法有很多,比如,我们可以这样:

viidiot@ubuntu:~/Desktop$ nl test.txt

     1 line one

     2 line two

     3 Hi,everybody,i'm linux-code!

     4    Linux-code,to be the best one!

也可以这样:

viidiot@ubuntu:~/Desktop$ cat -n test.txt

     1 line one

     2 line two

     3 Hi,everybody,i'm linux-code!

     4    Linux-code,to be the best one!

还可以这样:

viidiot@ubuntu:~/Desktop$ awk '{print NR, $0}' test.txt

1 line one

2 line two

3  Hi,everybody,i'm linux-code!

4    Linux-code,to be the best one!

所以,如果需要在文本test.txt中永久的插入行号并存档,你也行可以这样:

viidiot@ubuntu:~/Desktop$ cat -n test.txt >>tmp.txt;mv tmp.txt test.txt

viidiot@ubuntu:~/Desktop$ cat test.txt

     1 line one

     2 line two

     3 Hi,everybody,i'm linux-code!

     4    Linux-code,to be the best one!


本文就这么多了,最后留下一个实践内容,编写一个名叫highlightcode.sh程序,将一个原始的c程序,用sed将它进行格式化,使其能够高亮显示关键字。当然,你可以用纯c/c++去完成这个功能,但脚本可能可以更快的编写出来(相对于c程序)。(注:高亮是指其在浏览器中显示的效果。这里牵涉到css样式文件,并据此在原文件的基础上,插入一些样式,使其能高亮显示)

原始的显示效果:

image

高亮后的显示效果:

image

作者:Viidiot(阿呆) 微信公众号:linux-code

本文链接:http://www.cnblogs.com/jjdiaries/p/3377875.html

转载请保留作者及链接


推荐阅读
  • 微信小程序实现类似微博的无限回复功能,内置云开发数据库支持
    本文详细介绍了如何利用微信小程序实现类似于微博的无限回复功能,并充分利用了微信云开发的数据库支持。文中不仅提供了关键代码片段,还包含了完整的页面代码,方便开发者按需使用。此外,HTML页面中包含了一些示例图片,开发者可以根据个人喜好进行替换。文章还将展示详细的数据库结构设计,帮助读者更好地理解和实现这一功能。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 本文详细介绍了在Linux系统上编译安装MySQL 5.5源码的步骤。首先,通过Yum安装必要的依赖软件包,如GCC、GCC-C++等,确保编译环境的完备。接着,下载并解压MySQL 5.5的源码包,配置编译选项,进行编译和安装。最后,完成安装后,进行基本的配置和启动测试,确保MySQL服务正常运行。 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
  • Python学习:环境配置与安装指南
    Python作为一种跨平台的编程语言,适用于Windows、Linux和macOS等多种操作系统。为了确保本地已成功安装Python,用户可以通过终端或命令行界面输入`python`或`python3`命令进行验证。此外,建议使用虚拟环境管理工具如`venv`或`conda`,以便更好地隔离不同项目依赖,提高开发效率。 ... [详细]
  • Git命令基础应用指南
    本指南详细介绍了Git命令的基础应用,包括如何使用`git clone`从远程服务器克隆仓库(例如:`git clone [url/path/repository]`)以及如何克隆本地仓库(例如:`git clone [local/path/repository]`)。此外,还提供了常见的Git操作技巧,帮助开发者高效管理代码版本。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文详细介绍了定时器输入捕捉技术的原理及其应用。通过配置定时器通道的引脚模式为输入模式,并设置相应的捕获触发条件,可以实现对外部信号的精确捕捉。该技术在实时控制系统中具有广泛的应用,如电机控制、频率测量等场景。文中还提供了具体的配置步骤和示例代码,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 利用ZFS和Gluster实现分布式存储系统的高效迁移与应用
    本文探讨了在Ubuntu 18.04系统中利用ZFS和Gluster文件系统实现分布式存储系统的高效迁移与应用。通过详细的技术分析和实践案例,展示了这两种文件系统在数据迁移、高可用性和性能优化方面的优势,为分布式存储系统的部署和管理提供了宝贵的参考。 ... [详细]
  • CSS3 @font-face 字体应用技术解析与实践
    在Web前端开发中,HTML教程和CSS3的结合使得网页设计更加多样化。长期以来,Web设计师受限于“web-safe”字体的选择。然而,CSS3中的`@font-face`规则允许从服务器端加载自定义字体,极大地丰富了网页的视觉效果。通过这一技术,设计师可以自由选择和使用各种字体,提升用户体验和页面美观度。本文将深入解析`@font-face`的实现原理,并提供实际应用案例,帮助开发者更好地掌握这一强大工具。 ... [详细]
  • 本文深入解析了Java 8并发编程中的`AtomicInteger`类,详细探讨了其源码实现和应用场景。`AtomicInteger`通过硬件级别的原子操作,确保了整型变量在多线程环境下的安全性和高效性,避免了传统加锁方式带来的性能开销。文章不仅剖析了`AtomicInteger`的内部机制,还结合实际案例展示了其在并发编程中的优势和使用技巧。 ... [详细]
  • 在MySQL中实现时间比较功能的详细解析与应用
    在MySQL中实现时间比较功能的详细解析与应用。本文深入探讨了MySQL中时间比较的实现方法,重点介绍了`UNIX_TIMESTAMP`函数的应用。该函数可以接收一个日期时间参数,也可以不带参数使用,其返回值为Unix时间戳,便于进行时间的精确比较和计算。此外,文章还涵盖了其他相关的时间处理函数和技巧,帮助读者更好地理解和掌握MySQL中的时间操作。 ... [详细]
  • 在CentOS上部署和配置FreeSWITCH
    在CentOS系统上部署和配置FreeSWITCH的过程涉及多个步骤。本文详细介绍了从源代码安装FreeSWITCH的方法,包括必要的依赖项安装、编译和配置过程。此外,还提供了常见的配置选项和故障排除技巧,帮助用户顺利完成部署并确保系统的稳定运行。 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
author-avatar
ruishao520
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有