免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 9800 | 回复: 14
打印 上一主题 下一主题

sed -e :a -e '$q;N;5,$D;ba' 求解释 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-07-15 15:01 |只看该作者 |倒序浏览
# 显示文件中的最后4行 (模拟“tail”)
sed -e :a -e '$q;N;5,$D;ba'

$q: 结尾行退出循环
N:读取下一行到 pattern

5,$D 这个删除中的 5 针对的是哪个5

例如:
file:
1
2
3
4
5
6

5是真文件中的第5行, 还是读入pattern space 中的第5行?
解释一下这行代码的基本流程,看迷惑了。

论坛徽章:
0
2 [报告]
发表于 2011-07-15 15:26 |只看该作者
我大概了解意思了`
$q  退出`这个很好理解
N 将下一行读到  pattenrn space空间中
5,$D  删除pattenrn中的前5行数据
ba  无条件跳到标签  :a 进行下一轮 直到碰到$q
我可能理解的不太正确`
求高手来讲吧

论坛徽章:
0
3 [报告]
发表于 2011-07-15 15:31 |只看该作者
回复 2# yangyang1581


    差不多是这个意思,不是很难,刚接触理解费尽。

论坛徽章:
0
4 [报告]
发表于 2011-07-15 15:37 |只看该作者
D  删除 pattern space 内第一个 newline 字母 \ 前的数据。  
应该是前4行的数据给删了`
有点模糊

论坛徽章:
0
5 [报告]
发表于 2011-07-15 15:53 |只看该作者
本帖最后由 kr_zhang 于 2011-07-15 15:57 编辑

合计明白了,逻辑太复杂了。
就是一个数学关系, 总行数=删除行+未删除行
5,$D 其实就是 删除次数(也就是把前5,$次数的行给删除) ,未删除行其实就是5,所以剩余倒数4行没删除。

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
6 [报告]
发表于 2011-07-15 15:55 |只看该作者

论坛徽章:
0
7 [报告]
发表于 2011-07-15 15:59 |只看该作者
回复 6# waker


    这个太经典了,!

论坛徽章:
0
8 [报告]
发表于 2011-07-16 01:38 |只看该作者
回复 1# kr_zhang
  1. 用sedsed命令调试就可以查看到当前pattern和hold中得内容了!
  2. [root@redhat ~]# seq 6 | sedsed -d -e :a -e '$q;N;5,$D;ba'
  3. PATT:1$
  4. HOLD:$
  5. COMM::a
  6. COMM:$ q
  7. PATT:1$
  8. HOLD:$
  9. COMM:N
  10. PATT:1\n2$
  11. HOLD:$
  12. COMM:5,$ D
  13. PATT:1\n2$
  14. HOLD:$
  15. COMM:b a
  16. COMM:$ q
  17. PATT:1\n2$
  18. HOLD:$
  19. COMM:N
  20. PATT:1\n2\n3$
  21. HOLD:$
  22. COMM:5,$ D
  23. PATT:1\n2\n3$
  24. HOLD:$
  25. COMM:b a
  26. COMM:$ q
  27. PATT:1\n2\n3$
  28. HOLD:$
  29. COMM:N
  30. PATT:1\n2\n3\n4$
  31. HOLD:$
  32. COMM:5,$ D
  33. PATT:1\n2\n3\n4$
  34. HOLD:$
  35. COMM:b a
  36. COMM:$ q
  37. PATT:1\n2\n3\n4$
  38. HOLD:$
  39. COMM:N
  40. PATT:1\n2\n3\n4\n5$
  41. HOLD:$
  42. COMM:5,$ D
  43. PATT:2\n3\n4\n5$
  44. HOLD:$
  45. COMM::a
  46. COMM:$ q
  47. PATT:2\n3\n4\n5$
  48. HOLD:$
  49. COMM:N
  50. PATT:2\n3\n4\n5\n6$
  51. HOLD:$
  52. COMM:5,$ D
  53. PATT:3\n4\n5\n6$
  54. HOLD:$
  55. COMM::a
  56. COMM:$ q
  57. 3
  58. 4
  59. 5
  60. 6
复制代码

论坛徽章:
0
9 [报告]
发表于 2011-07-16 02:28 |只看该作者
迷惑的时候,要善于并勤于使用sedsed

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
10 [报告]
发表于 2011-07-16 02:29 |只看该作者
本帖最后由 yinyuemi 于 2011-07-16 02:49 编辑

回复 5# kr_zhang

  1. sed -e :a -e '$q;N;5,$D;ba
复制代码
先做个分解:
<:a> 标签a

<$q>: 好理解,最后一行的时候退出,不过注意的是,如果没有-n选项的话,会默认打印pattern空间的内容。
q [exit-code]
    This command only accepts a single address.

    Exit sed without processing any more commands or input. Note that the current pattern space is printed if auto-print is not disabled with the -n options. The ability to return an exit code from the sed script is a GNU sed extension.


<N>: 读取下一行到pattern空间,注意的是如果下一行没有内容,也就是最后一行的时候,会结束sed命令,它后面的任何命令都不会执行,这也就是大家经常使用$!N用法的原因。
N
    Add a newline to the pattern space, then append the next line of input to the pattern space. If there is no more input then sed exits without processing any more commands.


<5,$D>:
先看下D命令:删除pattern空间的第一行,启动下一个循环,但不读入下一行内容。
D
    If pattern space contains no newline, start a normal new cycle as if the d command was issued. Otherwise, delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of inpu


5,$ 如果满足行号在5到最后一行的条件,就执行其后的命令,就还是这里的D。

<ba> 无条件返回标签a,执行其后命令。

综合起来说下,
以seq 10 |sed -e :a -e '$q;N;5,$D;ba 为例:
首先sed读入第一行内容1,(此时行号为1),执行标签a,接着是$q,不满足条件,执行后面的N,读入下一行内容2,(此时行号为2,pattern 空间内容:1\n2),
执行5,$D,不满足条件,执行ba,返回标签a,(此时pattern空间仍然是1\n2),$q不满足条件不执行,执行N,读入下一行内容3,(此时行号为3,pattern 空间内容:1\n2\n3),
执行5,$D,不满足条件,执行ba,返回标签a,(此时pattern空间仍然是1\n2\n3),$q不满足条件不执行,执行N,读入下一行内容4,(此时行号为4,pattern 空间内容:1\n2\n3\n4),
执行5,$D,不满足条件,执行ba,返回标签a,(此时pattern空间仍然是1\n2\n3\n4),$q不满足条件不执行,执行N,读入下一行内容5,(此时行号为5,pattern 空间内容:1\n2\n3\n4\n5),执行5,$D,满足条件,删除pattern空间的第一行内容1,(此时pattern空间内容为2\n3\n4\n5),执行下一个循环,从$q开始,不满足条件不执行,接着执行N
,读入下一行内容6,(此时pattern空间内容为2\n3\n4\n5\n6,行号为6),执行5,$D,删除pattern空间第一行内容2,(此时pattern空间内容为3\n4\n5\6),以此类推,一直循环下去,
这样pattern空间会一直保存4行内容.
直到倒数第二行的时候,但执行完N命令之后,pattern 空间中内容为6\n7\n8\n9\n10,此时行号为10,执行5,$D,删除6,pattern空间剩下的就是 7\n8\n9\n10,当返回去执行$q时,终于满足条件,结束命令,由于没有-n选项,打印pattern空间内容。

评分

参与人数 1可用积分 +6 收起 理由
xiaopan3322 + 6 Shell版有一种精神,叫SS精神!!!

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP