shell中的${},##, %% , :- ,:+, ? 的使用

本文介绍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

利用${ } 还可针对不同的变数状态赋值(沒设定、空值、非空值): 
${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。(非空值時不作处理)
${#var} 可计算出变量值的长度:

${#file} 可得到27 ,因为/dir1/dir2/dir3/my.file.txt 是27个字节
<think> 我们注意到用户给出的命令是:$(date &#39;+%Y-%m-%d $H:%M:%S&#39;) 这个命令在shell中执行时,会尝试执行date命令并替换结果。但是,这个格式字符串中存在一个错误:在时间部分,用户使用$H,而正确的格式应该是%H(百分号,而不是美元符号)。 因此,正确的格式应该是:$(date &#39;+%Y-%m-%d %H:%M:%S&#39;) 下面我们将详细解释并给出正确代码。 </think>以下是对 `$(date &#39;+%Y-%m-%d $H:%M:%S&#39;)` 命令的分析和修正: ### 问题分析 这个命令有两个主要问题: 1. **格式字符串错误**:在时间部分使用了 `$H` 而不是 `%H` 2. **变量扩展错误**:`$H` 会被 shell 解释为环境变量 `H`,而不是日期格式符 ### 正确代码 ```bash # 正确的时间格式获取命令 current_time=$(date &#39;+%Y-%m-%d %H:%M:%S&#39;) echo "当前时间: $current_time" ``` ### 详细解释 #### 1. date 命令格式说明 date 命令使用 `+` 后跟格式字符串来指定输出格式: - `%Y`:4位年份(如 2023) - `%m`:2位月份(01-12) - `%d`:2位日期(01-31) - `%H`:2位小时(00-23) - `%M`:2位分钟(00-59) - `%S`:2位秒钟(00-59) #### 2. 常见错误对比 | 错误命令 | 问题 | 可能输出 | 正确格式 | |---------|------|---------|---------| | `$H:%M:%S` | `$H` 被解析为变量 | 如果 `H=12`,则输出 `12:34:56` | `%H:%M:%S` | | `$H%M%S` | 混合使用错误 | `12%M%S` | `%H%M%S` | | `%h` | 无效格式符 | `%h` 直接输出 | `%H` | #### 3. 完整日期格式示例 ```bash # 不同格式的时间输出 echo "ISO 格式: $(date &#39;+%Y-%m-%d %H:%M:%S&#39;)" echo "文件格式: $(date &#39;+%Y%m%d_%H%M%S&#39;)" echo "可读格式: $(date &#39;+%A, %B %d, %Y %I:%M:%S %p&#39;)" ``` #### 4. 高级用法:时区控制 ```bash # UTC 时间 utc_time=$(TZ=UTC date &#39;+%Y-%m-%d %H:%M:%S %Z&#39;) echo "UTC 时间: $utc_time" # 纽约时间 ny_time=$(TZ=America/New_York date &#39;+%Y-%m-%d %H:%M:%S %Z&#39;) echo "纽约时间: $ny_time" ``` #### 5. 日期计算 ```bash # 昨天的时间 yesterday=$(date -d "yesterday" &#39;+%Y-%m-%d&#39;) # 7天后的时间 next_week=$(date -d "7 days" &#39;+%Y-%m-%d&#39;) # 指定日期计算 specific_date=$(date -d "2023-12-31 + 1 month" &#39;+%Y-%m-%d&#39;) ``` ### 示例输出 ``` 当前时间: 2023-08-15 14:30:45 ISO 格式: 2023-08-15 14:30:45 文件格式: 20230815_143045 可读格式: Tuesday, August 15, 2023 02:30:45 PM UTC 时间: 2023-08-15 06:30:45 UTC 纽约时间: 2023-08-15 10:30:45 EDT ``` ### 在脚本中的使用建议 ```bash #!/bin/bash # 获取当前时间戳 timestamp=$(date &#39;+%Y%m%d_%H%M%S&#39;) # 创建带时间戳的日志文件 log_file="app_${timestamp}.log" touch "$log_file" # 在日志中记录时间 echo "[$(date &#39;+%Y-%m-%d %H:%M:%S&#39;)] 程序启动" >> "$log_file" # 执行程序... sleep 5 # 记录结束时间 echo "[$(date &#39;+%Y-%m-%d %H:%M:%S&#39;)] 程序结束" >> "$log_file" ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值