【Shell 编程设计】shell中${}和()的使用指南

简介: 【Shell 编程设计】shell中${}和()的使用指南

Shell编程中的字符串操作与变量处理

在编程的世界里,字符串和变量的处理是任何语言中都非常重要的一部分。在Shell编程中,这一点尤为明显。本文将深入探讨Shell中如何使用${}()进行高级字符串操作和变量处理。这些操作不仅能让你的代码更简洁,也能让你更加灵活地处理各种编程场景。

“代码是写给人看的,顺便能在机器上运行。” —— Donald Knuth

为什么需要高级字符串操作和变量处理?

在编程中,我们经常需要对字符串进行各种各样的操作,比如提取子字符串、替换字符、改变大小写等。同时,变量的动态处理也是编程中不可或缺的一部分。掌握这些高级操作,就像是给自己的工具箱里添加了一把瑞士军刀,无论是数据处理还是系统操作,都能让你游刃有余。

在这里,我将介绍一些常用但可能不太为人知的Shell字符串操作和变量处理技巧。这些技巧在实际编程中有着广泛的应用,掌握它们将大大提升你的编程效率。

“The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.” —— Brian W. Kernighan, co-author of “The C Programming Language”

现在,让我们开始这一段令人兴奋的学习之旅吧!

注意:本文中的代码示例主要使用Bash Shell环境。如果你使用的是其他Shell环境,大部分示例仍然适用,但某些细微的语法可能会有所不同。

接下来,请跟随我一起深入了解这些高级操作吧!

“Simplicity is prerequisite for reliability.” —— Edsger W. Dijkstra


shell中${}和()的含义

在 Shell 脚本中,$()${} 有不同的用途:

$()

$() 用于命令替换。它会执行括号内的命令,并将输出替换为该命令的标准输出。例如:

today=$(date)
echo "Today's date is $today"

这里,$(date) 会执行 date 命令,并将其输出保存在变量 today 中。

这与使用反引号 `(不是单引号)达到相同目的的旧语法相似,但更为现代,并允许嵌套。

${}

${} 主要用于变量替换和字符串操作。例如:

name="Alice"
echo "Hello, ${name}"

这里,${name} 会被替换为变量 name 的值,即 “Alice”。

更复杂的用法包括字符串切片、获取字符串长度、查找和替换等:

# 获取字符串长度
length=${#name}
# 截取子字符串
partial=${name:0:3}
# 查找和替换
new_name=${name/Alice/Bob}

${} 在以下情况下特别有用:

  1. 当变量名与周围的文本混淆时。例如,${name}_file${name}_file 不同。
  2. 执行更复杂的字符串操作,如上面的例子。

简而言之,$() 用于命令替换,而 ${} 用于变量替换和字符串操作。两者都是 Shell 脚本中常用的特性。

shell中${}和()的使用实例

截断功能

“${1^^}_DOC_CHANGE_PID” #变量转换为大写

“${1,}_DOC_CHANGE_PID” #变量转换为小写

${!DOC_CHANGE_PID} #取变量的值

"${1^^}_DOC_CHANGE_PID"  #变量转换为大写
"${1,,}_DOC_CHANGE_PID"  #变量转换为小写
${!DOC_CHANGE_PID} #取变量的值
  • ${file#*/}: 拿掉第一条/及其左边的字符串:dir1/dir2/dir3/my.file.txt
  • ${file##*/}: 拿掉最后一条/及其左边的字符串:my.file.txt
  • ${file#*.}: 拿掉第一个.及其左边的字符串:file.txt
  • ${file##*.}: 拿掉最后一个.及其左边的字符串:txt
  • ${file%/*}: 拿掉最后条/及其右边的字符串:/dir1/dir2/dir3
  • ${file%%/*}: 拿掉第一条/及其右边的字符串:(空值)
  • ${file%.*}: 拿掉最后一个.及其右边的字符串:/dir1/dir2/dir3/my.file
  • ${file%%.*}: 拿掉第一个.及其右边的字符串:/dir1/dir2/dir3/my

字符串提取

单一符号是最小匹配﹔两个符号是最大匹配。

  • ${file:0:5}:提取最左边的 5 个字节:/dir1
  • ${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2
  • 字符串替换
  • ${file/dir/path}:将第一个 dir 提换为 path:/path1/dir2/dir3/my.file.txt
  • ${file//dir/path}:将全部 dir 提换为 path:/path1/path2/path3/my.file.txt
  • 针对不同的变量状态赋值(没设定、空值、非空值)
  • ${file-my.file.txt}: 若$file没有设定,则使用my.file.txt作返回值。(空值及非空值时不作处理)
  • ${file:-my.file.txt}:若$file没有设定或为空值,则使用my.file.txt作返回值。(非空值时不作处理)
  • ${file+my.file.txt}: 若$file设为空值或非空值,均使用my.file.txt作返回值。(没设定时不作处理)
  • ${file:+my.file.txt}:若$file为非空值,则使用my.file.txt作返回值。(没设定及空值时不作处理)
  • ${file=my.file.txt}: 若$file没设定,则使用my.file.txt作返回值,同时将$file 赋值为 my.file.txt。(空值及非空值时不作处理)
  • ${file:=my.file.txt}:若$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。(非空值时不作处理)

注意:

":+"的情况是不包含空值的.

“:-”, ":="等只要有号就是包含空值(null).


变量的长度

${#file}

数组运算

  • A=(a b c def)
  • ${A[@]} 或 ${A[*]} 可得到 a b c def (全部组数)
  • ${A[0]} 可得到 a (第一个组数),${A[1]} 则为第二个组数…
  • ${#A[@]} 或 ${#A[*]} 可得到 4 (全部组数数量)
  • ${#A[0]} 可得到 1 (即第一个组数(a)的长度),${#A[3]} 可得到 3 (第四个组数(def)的长度)

示例

**

#介绍下Shell中的${}、##和%%使用范例,本文给出了不同情况下得到的结果。
#假设定义了一个变量为:
#代码如下:
file=/dir1/dir2/dir3/my.file.txt
#可以用${ }分别替换得到不同的值:
${file#*/}#删掉第一个 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}#删掉最后一个 /  及其左边的字符串:my.file.txt
${file#*.}#删掉第一个 .  及其左边的字符串:file.txt
${file##*.}#删掉最后一个 .  及其左边的字符串:txt
${file%/*}#删掉最后一个  /  及其右边的字符串:/dir1/dir2/dir3
${file%%/*}#删掉第一个 /  及其右边的字符串:(空值)
${file%.*}#删掉最后一个  .  及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}#删掉第一个  .   及其右边的字符串:/dir1/dir2/dir3/my
#记忆的方法为:
# 是 去掉左边(键盘上#在 $ 的左边)
#%是去掉右边(键盘上% 在$ 的右边)
#单一符号是最小匹配;两个符号是最大匹配
${file:0:5}#提取最左边的 5 个字节:/dir1
${file:5:5}#提取第 5 个字节右边的连续5个字节:/dir2
#也可以对变量值里的字符串作替换:
${file/dir/path}#将第一个dir 替换为path:/path1/dir2/dir3/my.file.txt
${file//dir/path}#将全部dir 替换为 path:/path1/path2/path3/my.file.txt

结语:编程、思考与持续成长

在编程的世界里,每一行代码都是一种表达,每一个问题都是一个挑战。正如我们在本文中探讨的 Bash 脚本,简单的代码背后往往蕴含着丰富的思考和解决问题的智慧。编程不仅是一种技术活动,更是一种思维的锻炼和人类创造力的体现。

正如Bjarne Stroustrup在《The C++ Programming Language》中所说:“编程是理解的艺术。”

从编程的角度看,每一个错误、每一个挑战都是一次成长的机会。这些“错误”实际上是我们与计算机、与问题、甚至与自己内心的一次深度对话。它们不仅仅是困扰,更是一种启示,引导我们去优化思维,去完善解决方案。

我诚挚地邀请大家加入这场关于编程和思考的旅程。无论你是编程的新手,还是经验丰富的开发者,都请不吝赐教,分享你的见解和经验。你的每一次互动,无论是点赞、评论、分享还是关注,都是对我持续创作和分享的最大鼓励和支持。

感谢你花时间阅读这篇文章,如果你觉得有价值,请不要忘记收藏和分享。也欢迎你对博客内容提出宝贵的建议和问题,因为每一个问题都可能是下一篇文章的起点。

让我们一起,在编程的道路上,持续学习,持续成长。

“代码如诗,智慧如光。” —— 未知

感谢阅读,期待与你再次相遇在编程和思考的交汇点。

目录
相关文章
|
3月前
|
SQL JavaScript 关系型数据库
MySQL Shell 使用指南
MySQL Shell 是一个强大且灵活的工具,它扩展了 MySQL 客户端的功能,使得数据库管理和运维工作更加便捷高效。
340 0
|
24天前
|
存储 Unix Shell
shell脚本编程基础
【9月更文挑战第4天】
35 12
|
23天前
|
Shell Linux
Shell 编程 编写hello word
Shell 编写hello word
40 5
|
1月前
|
Shell KVM 虚拟化
Shell 数组编程
【8月更文挑战第22天】 Shell 数组编程
42 10
|
1月前
|
Shell 数据处理 C++
【震撼揭秘】Python正则VS Shell正则:一场跨越编程边界的史诗级对决!你绝不能错过的精彩较量,带你领略文本处理的极致魅力!
【8月更文挑战第19天】正则表达式是文本处理的强大工具,在Python与Shell中有广泛应用。两者虽语法各异,但仍共享许多基本元素,如`.`、`*`及`[]`等。Python通过`re`模块支持丰富的功能,如非捕获组及命名捕获组;而Shell则依赖`grep`、`sed`和`awk`等命令实现类似效果。尽管Python提供了更高级的特性和函数,Shell在处理文本文件方面仍有其独特优势。选择合适工具需根据具体需求和个人偏好决定。
27 1
|
1月前
|
监控 Shell Linux
探索Linux操作系统下的Shell编程之魅力
【8月更文挑战第4天】本文旨在通过一系列精心设计的示例和分析,揭示在Linux环境下进行Shell编程的独特之处及其强大功能。我们将从基础语法入手,逐步深入到脚本的编写与执行,最终通过实际代码案例展现Shell编程在日常系统管理和自动化任务中的应用价值。文章不仅适合初学者构建扎实的基础,同时也为有一定经验的开发者提供进阶技巧。
42 11
|
2月前
|
JavaScript 前端开发 Shell
Shell 脚本编程保姆级教程(上)
Shell 脚本编程保姆级教程(上)
|
2月前
|
Shell Linux Perl
shell 编程中 awk ,wc ,$0,$1 等 命令的使用总结
shell 编程中 awk ,wc ,$0,$1 等 命令的使用总结
67 0
|
2月前
|
Shell Linux
Shell 脚本编程学习
Shell 脚本编程学习
32 0
|
2月前
|
Shell
Shell 脚本编程保姆级教程(下)
Shell 脚本编程保姆级教程(下)