免费注册 查看新帖 |

Chinaunix

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

sed 引号中的 ! 的解析问题 [复制链接]

论坛徽章:
1
双子座
日期:2013-10-17 00:46:45
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-15 22:11 |只看该作者 |倒序浏览
gs_dev_49_67:~ # echo "1
> 2"|sed '/1/!d'
-bash: !d': event not found
>
gs_dev_49_67:~ # echo "1
> 2"|sed '/1/\!d'
sed: -e expression #1, char 4: unknown command: `\'
gs_dev_49_67:~ # echo "1
> 2"|sed /1/\!d
1
gs_dev_49_67:~ #

把引号去掉,反而正确了,叉,这是神马情况呢?

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
2 [报告]
发表于 2011-08-15 23:30 |只看该作者
回复 1# xrzs1986
  1. $ echo '1
  2. 2' |sed '/1/! (空格)d'
  3. 1
复制代码

论坛徽章:
1
双子座
日期:2013-10-17 00:46:45
3 [报告]
发表于 2011-08-16 01:58 |只看该作者
回复 2# yinyuemi



1、想知道为什么引号内转义也不行?
2、sed中 ! 被shell解析问题:
echo "    <Channel1 ChannelID="1" MinNumWhenStartGame="1">
xxx
xxx
    </Channel1>"|sed '/</!d'
-bash: !d': event not found

----------------------------------为什么续行之后却又可以了呢?麻烦原因能描述的具体点?谢谢~
echo "    <Channel1 ChannelID="1" MinNumWhenStartGame="1">
xxx
xxx
    </Channel1>" \
|sed '/</!d'

==================================

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

回复 3# xrzs1986

可以先翻翻这两个帖子:
    http://bbs.chinaunix.net/viewthread.php?tid=1468927&extra=&page=1
    http://bbs.chinaunix.net/viewthread.php?tid=2333465
   
这种情况只会发生在命令行,在脚本中,!作为历史查询的功能是被关闭的,
我再罗嗦几句,呵呵,为什么命令行下会出现错误,这个和shell如何解释command line有关,其中主要的就是双引号和单引号还有转移符号\的使用。
这里我先引用下网中人前辈的解释:http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=4#pid1511745
“在 bash 中,常用的 quoting 有如下三種方法:
* hard quote:' ' (單引號),凡在 hard quote 中的所有 meta 均被關閉。
* soft quote: " " (雙引號),在 soft quoe 中大部份 meta 都會被關閉,但某些則保留(如 $ )。(註二)
* escape : \ (反斜線),只有緊接在 escape (跳脫字符)之後的單一 meta 才被關閉。”

具体到这个帖子,有下面几种情况:
1.

  1. echo "1
  2. 2" |sed '/1/!d'
  3. bash: !d': event not found

  4. #根据报错的情况判断,发生在bash解释command line的时候,当我们输入的command,使用了双引号,而且包含回车键换行的时,shell会逐行解释,比如变量的解释,内建命令的执行等,作command 重组的过程,最后合成一行。
  5. 这里把!作为历史查询命令在处理,因为历史中没有包含字符d的command line,所以报错。
  6. 如果在command line历史中存在一个包含字符d的命令,那又会出现什么情况呢?可以是试试:)
复制代码
2.

  1. echo "1
  2. 2"|sed '/1/! d'
  3. 1
  4. #加了空格,shell解释为字符,sed解释为“非”,执行成功!
复制代码
3.

  1. echo '1
  2. 2'|sed '/1/!d'
  3. 1
  4. #使用了单引号,关闭所有的meta,即使在输入包含回车键,也只是被认为一个new line的字符,shell不会按行作command重组,上面的代码相当于echo -e '1\n2' |sed '/1/!d' 这样一个单行command。
复制代码
4.

  1. echo "1
  2. 2" |\
  3. sed '/1/!d'
  4. 1
  5. # 使用了转义符\,和单引号是一个道理。
复制代码
如果错误的地方请大家指正

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
5 [报告]
发表于 2011-08-16 09:02 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
双子座
日期:2013-10-17 00:46:45
6 [报告]
发表于 2011-08-16 09:29 |只看该作者
回复 4# yinyuemi


    多谢SS兄的细心解答,很透彻~

论坛徽章:
0
7 [报告]
发表于 2011-08-16 09:38 |只看该作者
但是后面的 !d命令是包含在单引号里的为什么会扩展呢?

# echo "! d"
! d
# echo "!d"
echo "df -h"
df -h
# echo '!d'
!d

论坛徽章:
3
15-16赛季CBA联赛之辽宁
日期:2017-12-28 12:15:1015-16赛季CBA联赛之福建
日期:2017-12-28 12:26:5115-16赛季CBA联赛之新疆
日期:2018-03-07 15:09:17
8 [报告]
发表于 2011-08-16 11:26 |只看该作者
!  调用历史命令


[root@RAC2 ~]# history | awk '{print $2}' | grep '^f'
fdisk
find
find
find
find
find
fdisk
fuser
fuser
[root@RAC2 ~]# !f
fuser -k /u01/oracle/archrmt/
[root@RAC2 ~]# history | awk '{print $2}' | grep '^d'
date
date
date
dmesg
dmesg
dmesg
dmesg
date
diff
dbca
dbca
dbca
dbca
dbca
dbca
dbca
dbca
date
date
df
df
df
df
df
df
df
df
df
df
df
df
[root@RAC2 ~]# !d
df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdd5              20G  3.3G   16G  18% /
/dev/sdd1             190M   22M  159M  12% /boot
none                  7.9G     0  7.9G   0% /dev/shm
/dev/sdd3              39G  6.2G   31G  17% /home
/dev/sdd2              68G   22G   43G  34% /u01
/dev/sdb1             954M  411M  543M  44% /ocfs
192.168.1.100:/u01/oracle/rac2arch
                       68G   21G   43G  33% /u01/oracle/archrmt

论坛徽章:
3
15-16赛季CBA联赛之辽宁
日期:2017-12-28 12:15:1015-16赛季CBA联赛之福建
日期:2017-12-28 12:26:5115-16赛季CBA联赛之新疆
日期:2018-03-07 15:09:17
9 [报告]
发表于 2011-08-16 11:53 |只看该作者

  1. [root@ORA10g ~]# !d
  2. df -h
  3. Filesystem            Size  Used Avail Use% Mounted on
  4. /dev/sda2             9.5G  1.8G  7.3G  20% /
  5. /dev/sda8              30G   16G   13G  56% /opt
  6. /dev/sda6             4.8G  1.8G  2.8G  39% /home
  7. /dev/sda5             9.5G  4.6G  4.5G  51% /usr
  8. /dev/sda3             9.5G  1.7G  7.4G  19% /var
  9. /dev/sda1              99M   28M   66M  30% /boot
  10. tmpfs                1014M     0 1014M   0% /dev/shm
  11. /dev/sdb1              19G  2.4G   16G  14% /datafile
  12. /dev/sdb2              19G  1.9G   16G  11% /srcdir
  13. /dev/sdb5              30G  173M   29G   1% /bakup
  14. /dev/sdc1              68G   41G   24G  64% /oracledb
  15. /dev/sdd1              68G   23G   42G  35% /u01
  16. /dev/sde1              68G   37G   28G  57% /u02
  17. [root@ORA10g ~]# echo "1
  18. > 2"|sed '/1/!d'
  19. -bash: !d': event not found
  20. >
  21. > "
  22. 1


  23. [root@ORA10g ~]# echo "1
  24. > 2"
  25. 1
  26. 2
复制代码
这个怎么解释
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP