shell十三问之8: $(())与$()还有${}差在哪?

发表于 5年以前  | 总阅读数:1600 次

我们上一章介绍了()与{}的不同, 这次让我们扩展一下,看看更多的变化: $()与${}又是啥玩意儿呢?

在bash shell中, $()与``(反引号)都是用来做 命令替换(command substitution)的。

所谓的命令替换与我们第五章学过的变量替换差不多, 都是用来重组命令行: 完成 `` 或者$()里面的 命令,将其结果替换出来, 再重组命令行。

例如:

$ echo the last sunday is $(date -d "last sunday" +%Y-%m-%d)

如此便可方便得到上一个星期天的日期了...^_^

在操作上, 用$()或``都无所谓, 只是我个人比较喜欢用$(),理由是:

  1. ``(反引号)很容易与''(单引号)搞混乱,尤其对初学者来说。 有时在一些奇怪的字形显示中,两种符号是一模一样的(只取两点)。 当然了有经验的朋友还是一眼就能分辨两者。只是,若能更好的避免混乱, 又何乐而不为呢? ^_^

  2. 在多次的复合替换中, ``需要额外的转义(escape, )处理,而$()则比较直观。 例如,一个错误的使用的例子:

     command1 `command2 `command3` `

    原来的本意是要在command2 `command3` , 先将command3替换出来给command2处理, 然后再将command2的处理结果,给command1来处理。 然而真正的结果在命令行中却是分成了`command2`与 ``。

正确的输入应该如下:

    command1 `command2 \`command3\` `

要不然换成$()就没有问题了:

    command1 $(commmand2 $(command3))

只要你喜欢,做多少层的替换都没有问题~~~^_^

不过,$()并不是没有弊端的... 首先,``基本上可用在所有的unix shell中使用, 若写成 shell script,其移植性比较高。 而$()并不是每一种shell都能使用,我只能说, 若你用bash2的话,肯定没问题... ^_^

接下来,再让我们看看${}吧...它其实就是用来做 变量替换用的啦。 一般情况下,$var与${var}并没有啥不一样。 但是用${}会比较精准的界定变量名称的范围, 比方说:

$ A=B
$ echo $AB

原本是打算先将$A的结果替换出来, 然后在其后补一个字母B; 但命令行上, 真正的结果却是替换变量名称为AB的值出来... 若使用${}就没有问题了:

$ A=B
$ echo ${A}B
$ BB

不过,假如你只看到${}只能用来界定变量名称的话, 那你就实在太小看bash了。

为了完整起见,我这里再用一些例子加以说明${}的一些 特异功能: 假设我们定义了一个变量file为:

file=/dir1/dir2/dir3/my.file.txt

我们可以用${}分别替换获得不同的值:

1. shell字符串的非贪婪(最小匹配)左删除


${file#*/}  #其值为:dir1/dir2/dir3/my.file.txt

拿掉第一个/及其左边的字符串,其结果为: dir1/dir2/dir3/my.file.txt

${file#*.}  #其值为:file.txt

拿掉第一个.及其左边的字符串,其结果为: file.txt

2. shell字符串的贪婪(最大匹配)左删除:


${file##*/} #其值为:my.file.txt

拿掉最后一个/及其左边的字符串,其结果为: my.file.txt

${file##*.} #其值为:txt

拿掉最后一个.及其左边的字符串,其结果为: txt

3. shell字符串的非贪婪(最小匹配)右删除:


${file%/*}  #其值为:/dir1/dir2/dir3

拿掉最后一个/及其右边的字符串,其结果为: /dir1/dir2/dir3

${file%.*}  #其值为:/dir1/dir2/dir3/my.file

拿掉最后一个.及其右边的字符串,其结果为: /dir1/dir2/dir3/my.file

4. shell字符串的贪婪(最大匹配)右删除:


${file%%/*}  #其值为:其值为空。

拿掉第一个/及其右边的字符串,其结果为: 空串。

${file%%.*}  #其值为:/dir1/dir2/dir3/my。

拿掉第一个.及其右边的字符串,其结果为: /dir1/dir2/dir3/my。

Tips:

记忆方法:

#是去掉左边(在键盘上#$的左边);

%是去掉右边(在键盘上%$的右边);

单个符号是最小匹配;

两个符号是最大匹配;

5. shell字符串取子串:


 ${file:0:5} #提取最左边的5个字符:/dir1
 ${file:5:5} #提取第5个字符及其右边的5个字符:/dir2

shell字符串取子串的格式:${s:pos:length}, 取字符串s的子串:从pos位置开始的字符(包括该字符)的长度为length的的子串; 其中pos为子串的首字符,在s中位置; length为子串的长度;

Note: 字符串中字符的起始编号为0.

6. shell字符串变量值的替换:


${file/dir/path}  #将第一个dir替换为path:/path1/dir2/dir3/my.file.txt
${file//dir/path} #将全部的dir替换为path:/path1/path2/path3/my.file.txt

shell字符串变量值的替换格式:

  • 首次替换: ${s/src_pattern/dst_pattern} 将字符串s中的第一个src_pattern替换为dst_pattern。

  • 全部替换: ${s//src_pattern/dst_pattern} 将字符串s中的所有出现的src_pattern替换为dst_pattern.

7. ${}还可针对变量的不同状态(没设定、空值、非空值)进行赋值:


  • ${file-my.file.txt} #如果file没有设定,则使用 使用my.file.txt作为返回值, 否则返回${file};(空值及非空值时,不作处理。);

  • ${file:-my.file.txt} #如果file没有设定或者${file}为空值, 均使用my.file.txt作为其返回值,否则,返回${file}.(${file} 为非空值时,不作处理);

  • ${file+my.file.txt} #如果file已设定(为空值或非空值), 则使用my.file.txt作为其返回值,否则不作处理。(未设定时,不作处理);

  • ${file:+my.file.txt} #如果${file}为非空值, 则使用my.file.txt作为其返回值,否则,(未设定或者为空值时)不作处理。

  • ${file=my.file.txt} #如果file为设定,则将file赋值为my.file.txt,同时将${file}作为其返回值;否则,file已设定(为空值或非空值),则返回${file}。

  • ${file:=my.file.txt} #如果file未设定或者${file}为空值, 则my.file.txt作为其返回值, 同时,将${file}赋值为my.file.txt,否则,(非空值时)不作处理。

  • ${file?my.file.txt} #如果file没有设定,则将my.file.txt输出至STDERR, 否侧, 已设定(空值与非空值时),不作处理。

  • ${file:?my.file.txt} #若果file未设定或者为空值,则将my.file.txt输出至STDERR,否则, 非空值时,不作任何处理。

Tips:

以上的理解在于,你一定要分清楚,unsetnull以及non-null这三种状态的赋值; 一般而言,与null有关,若不带:, null不受影响; 若带 :, 则连null值也受影响。

8. 计算shell字符串变量的长度:${#var}


 ${#file}  #其值为27, 因为/dir1/dir2/dir3/my.file.txt刚好为27个字符。

9. bash数组(array)的处理方法


接下来,为大家介绍一下bash的数组(array)的处理方法。 一般而言, A="a b c def" 这样的变量只是将$A替换为一个字符串, 但是改为 A=(a b c def), 则是将$A定义为数组....

1). 数组替换方法可参考如下方法:
${A[@]} #方法一
${A[*]} #方法二

以上两种方法均可以得到:a b c def, 即数组的全部元素。

2). 访问数组的成员:
${A[0]}

其中,${A[0]}可得到a, 即数组A的第一个元素, 而 ${A[1]}则为数组A的第二元素,依次类推。

3). 数组的length:
${#A[@]} #方法一
${#A[*]} #方法二

以上两种方法均可以得到数组的长度: 4, 即数组的所有元素的个数。

回忆一下,针对字符串的长度计算,使用${#str_var}; 我们同样可以将该方法应用于数组的成员:

${#A[0]}

其中,${#A[0]}可以得到:1,即数组A的第一个元素(a)的长度; 同理,${#A[3]}可以得到: 3, 即数组A的第4个元素(def)的长度。

4). 数组元素的重新赋值:
A[3]=xyz

将数组A的第四个元素重新定义为xyz。

Tips:

诸如此类的...

能够善用bash的$()与${}可以大大提高及 简化shell在变量上的处理能力哦~~~^_^

10. $(())作用:


好了,最后为大家介绍$(())的用途吧: $(())是用来作整数运算的

在bash中, $(())的整数运算符号大致有这些:

  • +- * / #分别为"加、减、乘、除"。
  • % #余数运算,(模数运算)
  • & | ^ ! #分别为"AND、OR、XOR、NOT"运算。

例如:

$ a=5; b=7; c=2;
$ echo $(( a + b * c ))
19
$ echo $(( (a + b)/c ))
6
$ echo $(( (a * b) % c ))
1

$(())中的变量名称, 可以在其前面加 $符号来替换, 也可以不用,如: $(( $a + $b * $c )) 也可以得到19的结果。

此外,$(())还可作不同进制(如二进制、八进制、十六进制)的运算, 只是输出结果均为十进制的。

echo $(( 16#2a )) #输出结果为:42,(16进制的2a)

以一个实用的例子来看看吧 : 假如当前的umask是022,那么新建文件的权限即为:

$ umask 022
$ echo "obase=8; $(( 8#666 & (8#777 ^ 8#$(umask)) ))" | bc
644

事实上,单纯用(())也可以重定义变量值,或作testing:

a=5; ((a++)) #可将$a 重定义为6
a=5; ((a--)) #可将$a 重定义为4
a=5; b=7; ((a< b)) #会得到0 (true)返回值。

常见的用于(())的测试符号有如下这些:

符号 符号名称
< 小于号
> 大于号
<= 小于或等于
>= 大于或等于
== 等于
!= 不等于

Note:

使用(())作整数测试时, 请不要跟[]的整数测试搞混乱了。

更多的测试,我们将于第10章为大家介绍。

怎样? 好玩吧... ^_^

okay,这次暂时说这么多...

上面的介绍,并没有详列每一种可用的状态, 更多的,就请读者参考手册文件(man)吧...

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
如何查看docker镜像里的文件 5年以前  |  5480次阅读
Shell语法快速入门 5年以前  |  3160次阅读
Shell命令在后台运行程序 5年以前  |  3069次阅读
Shell脚本编程30分钟入门 5年以前  |  1893次阅读
 目录