Chinaunix首页 | 论坛 | 博客
  • 博客访问: 477081
  • 博文数量: 100
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 955
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-21 09:30
文章分类

全部博文(100)

文章存档

2017年(1)

2016年(16)

2015年(83)

我的朋友

分类: 嵌入式

2015-08-24 03:27:05

sed -e 's/\(.*\)\.\w/\1.o/' 
这句shell的作用是: 将所有以一个字符或数字为后缀的文件名改为以o为后缀的文件名

下面来分析这行命令,首先了解sed的替换功能的格式:
[ a d d r e s s [address]] s/ pattern-to-find /replacement-pattern/[g p w n]
s选项通知 s e d这是一个替换操作,并查询 p a t t e r n - t o - f i n d,成功后用r e p l a c e m e n t - p a t t e r n替
换它。
替换选项如下:
g 缺省情况下只替换第一次出现模式,使用 g选项替换全局所有出现模式。
p 缺省s e d将所有被替换行写入标准输出,加 p选项将使 - n选项无效。 - n选项不打印输出
结果。
w 文件名 使用此选项将输出定向到一个文件。

所以,如果只是简单的替换,如将a改为b,格式应为 sed -e 's/a/b/'
但是这里用了后向引用,先用\(.*\)\.\w匹配文件名(包含后缀),再修改为\1.o,也就是文件名加上.o后缀。
假设有个源文件test.c,那么
\(.*\)\.\w完全匹配test.c,这里\(.*\)\.\w包含了2个子表达式\(.*\)\匹配test,.\w匹配.c ,现在要保持test不变,只修改.c为.o,就需要后向引用了,\1就是引用第一个子表达式即\(.*\)\,也就是test,所以test.c就改为test.o了。


测试:echo test.log |sed -n '/\(.*\)\.\w/'p ,匹配到test.log并打印
echo test.log |sed -e 's/\(.*\)\.\w/\1.o/'        替换为test.oog
参考:
[求助]sed -e 's/\(.*\)\.\w/\1.o/' 什么意思呢?
style="white-space:normal;">

Sed&awk笔记之sed篇  (这里提到表达式分组,并且说明扩展的正则表达式中分组的括号不需要用反斜杠转义)
http://blog.csdn.net/a81895898/article/details/8482387

19.7 POSIX基本正则表达式和扩展正则表达式的比较
/>
[跟我学正则表达式] 7. 使用子表达式
http://blog.sina.com.cn/s/blog_7546636b0101gxgl.html

[跟我学正则表达式] 8. 使用后向引用:
http://blog.sina.com.cn/s/blog_7546636b0101gxgn.html

shell 二十篇

正则表达式的语法
/>
#!/bin/bash
echo test.log |sed -e 's/\(.*\)\.\w/\1.o/'

补充:
.*匹配任意长度字符
打印匹配到的行:
input="255 heads, 63 sectors/track, 10443 cylinders, total 167772160 sectors"
echo $input | sed -n  '/.*total.*/'p 

将total 之前的所有字符替换为空白:
input="255 heads, 63 sectors/track, 10443 cylinders, total 167772160 sectors"
echo $input | sed -e 's/.*total \(.*\)/\1/'
或者使用扩展正则ERE:   echo $input | sed -r -e 's/.*total (.*)/\1/' 
注意-r一定要在-e的前面,因为后面的替换操作是-e选项执行的。

另一种方法:
#!/bin/bash
input="255 heads, 63 sectors/track, 10443 cylinders, total 167772160 sectors"
output=`echo ${input#*total} | awk '{print $1}'`
echo $output
阅读(2217) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~