学习shell脚本遇到的问题

kainme 2019-01-11 04:29:02
这行脚本我没看懂怎么实现的,求大佬门帮忙分析一下过程。感谢

题目
7、取出一个文件的绝对路径名称(不包含该文件本身) 下面是正确答案

echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\1@g' 输出为 /etc/

但我没太理解
(/.*/) 应该可以匹配整行不不管多长只要是/开头/结尾,中间不管有几个/都是没问题的对吗?
验证了一下没问题:


[^/]+根据这个意思是匹配非字符/的所有其它字符
验证了一下发现也匹配到了整行,不是很理解:


/? 是匹配0个或1个/,试了一下也是整行


求大佬帮忙分析一下。谢谢~
...全文
130 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
kainme 2019-01-12
  • 打赏
  • 举报
回复
引用 3 楼 十五十六 的回复:
好吧 讲道理,刚才我傻逼了。 sed需要匹配到整行才会进行替换,就比如你的第二个命令 [root@localhost ~]# echo "/etc/rc.d/" | sed -r 's@([^/])@\1@' /etc/rc.d/ 这里文本是/etc/rc.d/ 而你sed的模式是([^/])只匹配单个非/字符,所以这一行就匹配失败了,所以输出了整行, 如果你要测的话可以改成 [root@localhost ~]# echo "/etc/rc.d/" | sed -r 's@/([^/]).*@\1@' e 在这个命令里文本是/etc/rc.d/,匹配的模式是/([^/]).*这时候就能匹配到这一行了,所以只输出了匹配到的单个字符e 你的第三个命令也是同样的问题,匹配模式没有匹配成功,所以输出了整行
明白了,是我自己弄混了,谢谢
kainme 2019-01-12
  • 打赏
  • 举报
回复
引用 3 楼 十五十六 的回复:
好吧 讲道理,刚才我傻逼了。 sed需要匹配到整行才会进行替换,就比如你的第二个命令 [root@localhost ~]# echo "/etc/rc.d/" | sed -r 's@([^/])@\1@' /etc/rc.d/ 这里文本是/etc/rc.d/ 而你sed的模式是([^/])只匹配单个非/字符,所以这一行就匹配失败了,所以输出了整行, 如果你要测的话可以改成 [root@localhost ~]# echo "/etc/rc.d/" | sed -r 's@/([^/]).*@\1@' e 在这个命令里文本是/etc/rc.d/,匹配的模式是/([^/]).*这时候就能匹配到这一行了,所以只输出了匹配到的单个字符e 你的第三个命令也是同样的问题,匹配模式没有匹配成功,所以输出了整行
谢谢老哥,我按照你的例子改了一下 把 /去掉了 echo "/etc/rc.d/" | sed -r 's@([^/]).*@\1@' 为什么输出了 /e   还是有点不理解。取一个非/的字符那也应该是e呀
十五十六 2019-01-11
  • 打赏
  • 举报
回复
好吧 讲道理,刚才我傻逼了。 sed需要匹配到整行才会进行替换,就比如你的第二个命令
[root@localhost ~]# echo "/etc/rc.d/" | sed -r 's@([^/])@\1@'
/etc/rc.d/
这里文本是/etc/rc.d/ 而你sed的模式是([^/])只匹配单个非/字符,所以这一行就匹配失败了,所以输出了整行,

如果你要测的话可以改成
[root@localhost ~]# echo "/etc/rc.d/" | sed -r 's@/([^/]).*@\1@'
e

在这个命令里文本是/etc/rc.d/,匹配的模式是/([^/]).*这时候就能匹配到这一行了,所以只输出了匹配到的单个字符e

你的第三个命令也是同样的问题,匹配模式没有匹配成功,所以输出了整行
十五十六 2019-01-11
  • 打赏
  • 举报
回复
有一个调试的小技巧,你先把这个命令写到一个bash脚本中
[root@localhost ~]# cat test.sh
#!/bin/bash
echo "/etc/rc.d/sdff/" | sed -r 's@([^/])@@'

然后运行这个脚本

[root@localhost ~]# sh -x test.sh
+ echo /etc/rc.d/sdff/
+ sed -r 's@([^/])@@'
/tc/rc.d/sdff/
可以看到先运行了 echo然后sed,([^/])表示只匹配一个非/的字符,这里匹配到了e,所以e没了
然后我们修改一下脚本,然后运行
[root@localhost ~]# sh -x test.sh
+ sed -r 's@([^/])@@'
+ echo /etc/rc.d/sdff/
/tc/rc.d/sdff/
[root@localhost ~]# vim test.sh
[root@localhost ~]# sh -x test.sh
+ sed -r 's@([^/])@\1@'
+ echo /etc/rc.d/sdff/
/etc/rc.d/sdff/

这里可以看到 先sed 然后再echo了,所以是输出整行,但是为什么是先sed再 echo这个我还没想通。

zclinux_ 2019-01-11
  • 打赏
  • 举报
回复
第二个sed中的“^”这个代表的是以什么开头,当你用了“^/”的话,shell就认为是以“/”为开头的
第三个sed中的“/?”貌似用法有点问题

19,613

社区成员

发帖
与我相关
我的任务
社区描述
系统使用、管理、维护问题。可以是Ubuntu, Fedora, Unix等等
社区管理员
  • 系统维护与使用区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧