免费注册 查看新帖 |

Chinaunix

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

[文本处理] 关于字符串非空判断的疑问 [复制链接]

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-03-18 10:40 |只看该作者 |倒序浏览
大家好!
我有一个问题向大家请教!

我们知道对于字符串的非空判断可以有很多种写法。
比如:[ -n $x ] 和 [ A"$x" = "A" ]
一直以来,我以为这两者应该是等价的。
比如,从下面的几条命令,我们可以发现两者的执行结果是一样的。
  1. [root@hp8 ~]# unset x
  2. [root@hp8 ~]# [ -n $x ] && echo yes || echo no
  3. yes
  4. [root@hp8 ~]# [ A"$x" = "A" ] && echo yes || echo no
  5. yes
复制代码
但是今天我发现在下面的一个程序中,两者得到的结果是完全不一样的。
程序1:
  1. c=10
  2. unset x
  3. while ( [ A$x = "A" ] && [ $c -gt 0 ] ); do
  4. x="ABCDEFG"
  5. echo "c=$c x=$x"
  6. [ A$x = "A" ] &&sleep 1 && c=$(($c-1))
  7. done
复制代码
程序2:
  1. c=10
  2. unset x
  3. while ( [ -n $x ] && [ $c -gt 0 ] ); do
  4. x="ABCDEFG"
  5. echo "c=$c x=$x"
  6. [ -n $x ] &&sleep 1 && c=$(($c-1))
  7. done
复制代码
程序1的执行结果是:
  1. c=10 x=ABCDEFG
复制代码
而程序2的执行结果是:
  1. c=10 x=ABCDEFG
  2. c=9 x=ABCDEFG
  3. c=8 x=ABCDEFG
  4. c=7 x=ABCDEFG
  5. c=6 x=ABCDEFG
  6. c=5 x=ABCDEFG
  7. c=4 x=ABCDEFG
  8. c=3 x=ABCDEFG
  9. c=2 x=ABCDEFG
  10. c=1 x=ABCDEFG
复制代码
为什么会有这样的区别呢?
求解释。
谢谢!

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
2 [报告]
发表于 2015-03-18 10:44 |只看该作者
还有 [ -z $x ] 的执行结果和 [ A"$x" = "A" ] 是一样的。

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
3 [报告]
发表于 2015-03-18 11:07 |只看该作者
回复 2# bikkuri
   [ -n "$x" ]    用引号试试


   

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
4 [报告]
发表于 2015-03-18 11:12 |只看该作者
本帖最后由 聆雨淋夜 于 2015-03-18 11:28 编辑

-n  不为空时真
-z   为空时真
你搞反了吧
你搞反的原因是   [ -n $x ] && echo yes || echo no    这种写法是错的    $x要用引号

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
5 [报告]
发表于 2015-03-18 16:43 |只看该作者
本帖最后由 bikkuri 于 2015-03-18 16:45 编辑

啊?!原来是没有加引号的问题!
为什么加了引号和不加引号结果完全不一样呢?
  1. [enb@hp8 ~]$ [ -n $x ] && echo yes || echo no
  2. yes
  3. [enb@hp8 ~]$ [ -n "$x" ] && echo yes || echo no
  4. no
复制代码
-n  不为空时真 也就是说 $x不为空 而"$x"为空 吗?这个不太理解,各位高手指点一下?
但是但是但是,为什么对于-z来说加不加引号结果都一样呢?
  1. [enb@hp8 ~]$ [ -z "$x" ] && echo yes || echo no
  2. yes
  3. [enb@hp8 ~]$ [ -z $x ] && echo yes || echo no
  4. yes
复制代码
这个太奇怪了喔!
首先能解释一下加引号和不加引号有什么区别吗?
为什么很多时候加不加引号结果都是一样的,偶尔又有结果不一样的情况呢?

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
6 [报告]
发表于 2015-03-18 17:16 |只看该作者
本帖最后由 聆雨淋夜 于 2015-03-20 00:43 编辑

回复 5# bikkuri
[  及test是命令,其后的变量经过替换后会按IFS切割,如果没有引号
[ -n $x ] && echo yes || echo no
shell处理后是[ -n  ] && echo yes || echo no
当test或[ ]有且仅有一个非空参数(此处是 “-n” )时,返回恒为真  ,这也解释了为什么-z没引号时也为真

所以此处要么用引号防止切割(这样就还有一个参数" "),要么用[[ ]]([[ ]]不是命令,不做切割)



   

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
7 [报告]
发表于 2015-03-18 21:06 |只看该作者
原来是这样!
明白了。
太感谢了!
回复 6# 聆雨淋夜


   

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
8 [报告]
发表于 2015-03-19 09:41 |只看该作者
回复 6# 聆雨淋夜


    变量替换后不会按IFS切割吧。

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
9 [报告]
发表于 2015-03-19 10:50 |只看该作者
打开ABS,看看第90页。

Advanced Bash-Scripting Guide 3.9.1 中文版.pdf
http://bbs.chinaunix.net/thread-1610033-1-1.html

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
10 [报告]
发表于 2015-03-19 21:55 |只看该作者
回复 8# blackold
额…  黑哥这回你要多说点,我以前就这个问题问过你。
man bash有下面一段:
IFS    The Internal Field Separator that is used for word splitting after expansion and to split lines into words  with
              the read builtin command.  The default value is ''<space><tab><newline>''.

我以为这里的expansion就是指Parameter Expansion、Command Substitution、Arithmetic Expansion
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP