标题: sed -n "/str1/,/str2/p" file 到底是什么意思?(附例) [打印本页]
作者: 踏沙行 时间: 2018-9-4 08:25 标题: sed -n "/str1/,/str2/p" file 到底是什么意思?(附例)
本帖最后由 踏沙行 于 2018-9-4 08:27 编辑
已知1.txt内容如下:- 1:basktop at time to door
- 2:basktop at time to floor
- 3:bathome is webbbs
- 4:you can not do it
- 5:yes you need to watch the game
- 6:he is write for bat
- 7:he is write for bat
- 8:you can not do it
复制代码
命令:
sed -n /at/,/is/p 1.txt
或者 sed -n "/at/,/is/p" 1.txt
结果都如下:- 1:basktop at time to door
- 2:basktop at time to floor
- 3:bathome is webbbs
- 5:yes you need to watch the game
- 6:he is write for bat1
- 7:he is write for bat2
- 8:you can not do it2
复制代码
请问,这个第8行为什么会被匹配?
附:使用环境 —— win7 64bit,sed版本:sed (GNU sed) 4.4,论坛第三方专区提供的版本(单行版)
作者: ai20110304 时间: 2018-9-4 09:05
回复 1# 踏沙行
sed 默认的命令执行范围是全局编辑的,如果不明确指定行的话,命令会在所有输入行上执行,如果想仅对其中部分行执行命令,可以使用地址限制。如果给了 2 个地址,即地址对(地址范围),则命令匹配的这个地址范围内执行,但是需要注意的是:对于像 "addr1,addr2" 这种形式的地址匹配,如果addr1 匹配,则匹配成功,"开关"打开,在该行上执行命令,此时不管 addr2 是否匹配,即使 addr2 在 addr1 这一行之前;接下来读入下一行,如果addr2 匹配,则执行命令,同样开关"关闭";如果 addr2 在 addr1 之后,则一直处理到匹配为止,换句话说,如果 addr2 一直不匹配,则开关一直不关闭,因此会持续执行命令到最后一行。
第四行过后,进行第二次匹配,以第一个地址匹配开始,不满足第二个条件,继续执行到文件结束。
作者: Batcher 时间: 2018-9-4 09:17
参考:
http://bbs.chinaunix.net/thread-1689518-8-1.html#pid12064955
Row Number | /at/ | /is/ | Range Operator | 备注 |
1 | TRUE | | TRUE | Once the left operand is true, the range operator stays true |
2 | | FALSE | TRUE | |
3 | | TRUE | TRUE | until the right operand is true, after which the range operator becomes false again |
4 | FALSE | | FALSE | |
5 | TRUE | | TRUE | Once the left operand is true, the range operator stays true |
6 | | TRUE | TRUE | until the right operand is true, after which the range operator becomes false again |
7 | TRUE | | TRUE | Once the left operand is true, the range operator stays true |
8 | | FALSE | TRUE | 只要无法匹配到/is/,不管后面有多少行都会输出 |
作者: Batcher 时间: 2018-9-4 09:21
回复 2# ai20110304
第四行后面还有满足的
作者: 踏沙行 时间: 2018-9-4 14:22
回复 2# ai20110304
谢谢楼上两位大神指导。
那么,当我想匹配以下目标时,用sed怎么实现呢?
1、从包含str1的行开始,到包含str2的行结束
2、匹配包含str1或str2的行
作者: Batcher 时间: 2018-9-4 14:40
回复 5# 踏沙行
第二种场景比较简单,以下两种写法都行:复制代码
- sed -n -r "/(at|is)/p" 1.txt
复制代码
作者: ai20110304 时间: 2018-9-4 15:16
回复 4# Batcher
第一个开启多条命令执行:- sed -n "/at/,/is/p; /is/q" 1.txt
复制代码
第二个是或的关系,支持扩展正则表达式 | 符号,需用-r 选项:- sed -n -r "/(at|is)/p" 1.txt
复制代码
作者: 踏沙行 时间: 2018-9-4 15:28
本帖最后由 踏沙行 于 2018-9-4 16:17 编辑
回复 7# ai20110304
谢谢,谢谢@batcher
七楼第一条命令,能讲讲是什么意思吗?
另外,这种使用方法有一个坑,比如改成
set -n "/is/,/at/p;/at/q" 1.txt
输入结果为空,原因是“at”和“is”都在第一行,结果/at/q即直接关闭输出,把匹配第一条pattern的行输出也关闭了。
那么,能不能在第1个分号后,跳转到下一行开始执行呢?sed中有个n指令,是跳到下一行执行。但是不知道在这个语句中,怎么写才能实现该效果- sed "/abc/{n;d}" 1.txt:将1.txt中包含"abc"的下一行删除
- sed "/abc/{n;s/ef/fe/g}" 1.txt:将1.txt中包含”abc”的下一行中的"ef"全部替换为"fe"
复制代码
请问上一句set -n "/is/,/at/p;/at/q" 1.txt,怎么改可以实现如上效果?
作者: Batcher 时间: 2018-9-4 17:41
回复 8# 踏沙行 - sed -n "/at/{:a;N;/is/{/at.*\n.*is/p;d};ba}" 1.txt
复制代码
作者: 踏沙行 时间: 2018-9-4 17:58
回复 9# Batcher - H:\>sed -n "/at/{:a;N;/is/{/at.*\n.*is/p;d};ba}" 1.txt
- 1:basktop at time to door
- 2:basktop at time to floor
- 3:bathome is webbbs
- 5:yes you need to watch the game
- 6:he is write for bat
复制代码
結果好像还是多了几行啊
作者: Batcher 时间: 2018-9-4 18:57
回复 10# 踏沙行
多了哪几行?
作者: 踏沙行 时间: 2018-9-5 07:52
回复 11# Batcher
不好意思,我没有表达清楚:
1、打印,从包含"at"的行,到包含"is"的行,匹配一次即停止打印。若后面还有从“at”到“is"的,不再打印。
2、打印,若只有包含"at"的行,而无包括"is"的行,则只打印含at的行
作者: Batcher 时间: 2018-9-5 13:46
回复 12# 踏沙行
这两个条件需要分别写成两个不同的命令?还是一条命令同时满足两个条件呢?
满足条件1的代码:- sed -n "/at/{:a;N;/is/{/at.*\n.*is/p;q};ba}" 1.txt
复制代码
作者: 踏沙行 时间: 2018-9-5 18:39
回复 13# Batcher
谢谢,能讲讲a N ba指令是什么意思吗?
网上对N的介绍看不明白,另外,没有看到a b这两个指令的使用说明
作者: Batcher 时间: 2018-9-5 20:33
回复 14# 踏沙行
N, n, H, h, G, g, x
搞清楚 pattern space 和 hold space 这两个概念才能理解这些命令的具体作用。
b label, t label, P, D
sed里面没有if, for这种分支和循环语句,但是可以通过上面这几个命令实现流程控制。
《O’Reilly sed & awk 2nd Edition》里面有每个命令具体的讲解和实例
http://bbs.bathome.net/thread-13203-1-1.html
如果每个命令的作用都搞懂了,但就是看不懂一些复杂的命令组合是什么意思,可以使用 sedsed 来观察一下命令执行过程中 pattern space 和 hold space 的变化就明白了:
http://bbs.bathome.net/thread-15582-1-1.html
作者: 踏沙行 时间: 2018-9-10 10:52
本帖最后由 踏沙行 于 2018-9-10 11:09 编辑
回复 15# Batcher
sedsed调试一文所介绍的例子,来自于网页,但是网页挂了,不知道怎么调试了。
我自己的高度方案,结果不正确。
附:我自己的调试方案:
1、H:\a.txt内容为:复制代码
2、从这里下载了sedsed1.0(http://aurelio.net/projects/sedsed/sedsed-1.0),将后缀改为.py,然后执行如下内容,结果出错- H:\>python sedsed.py -d --hide=hold "n;d" b.txt
- File "sedsed.py", line 96
- """
- ^
- SyntaxError: invalid syntax
复制代码
【注】我的python版本:Python 3.6.0;操作系统:win7 64位
作者: Batcher 时间: 2018-9-10 11:10
回复 16# 踏沙行
那个是 sedsed 的源代码,不只是案例介绍。你试试从这个网址复制下来 http://aurelio.net/projects/sedsed/
作者: Batcher 时间: 2018-9-10 11:17
sedsed 源码也已经上传到帖子里面了
http://bbs.bathome.net/thread-15582-1-1.html
作者: 踏沙行 时间: 2018-9-10 12:42
回复 18# Batcher
下载了论坛提供的sedsed.zip,解压后和目标文档放在同一目录,操作结果如下:- H:\>dir *.py
- 驱动器 H 中的卷没有标签。
- 卷的序列号是 893B-2135
-
- H:\ 的目录
-
- 2015-05-11,周一 16:00 52,851 sedsed.py
- 1 个文件 52,851 字节
- 0 个目录 262,617,034,752 可用字节
-
-
- H:\>
- H:\>type b.txt
- 1
- 2
- 3
- 4
- 5
- H:\>
-
- H:\>python sedsed.py -d --hide=hold "n;d" b.txt
- File "sedsed.py", line 96
- """
- ^
- SyntaxError: invalid syntax
复制代码
不知道错在哪里了?
作者: Batcher 时间: 2018-9-10 12:57
回复 19# 踏沙行
试试 Python 2.x
作者: 踏沙行 时间: 2018-9-10 22:34
好的,谢谢
作者: tigerpower 时间: 2018-12-2 13:22
本帖最后由 tigerpower 于 2018-12-2 13:56 编辑
回复 12# 踏沙行 - sed -n "/at/{:a;/at.*is/{p;q1};N;ba}" 1.txt && sed -n "/is/q1" 1.txt && sed -n "/at/p" 1.txt
复制代码
13楼的代码有bug,如果第一次匹配at的那一行又匹配is,则不会打印任何行。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |