博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 变量大括号,linux – 如何使用大括号扩展变量
阅读量:4964 次
发布时间:2019-06-12

本文共 2136 字,大约阅读时间需要 7 分钟。

使用

brace expansion的序列表达形式({< numFrom> ..< numTo>})的变量仅适用于ksh和zsh,但遗憾的是,不在bash中(并且(大多数情况下)严格来说仅限POSIX特征的shell如破折号根本不支持撑杆扩张,因此应完全避免撑杆扩展/ bin / sh).

鉴于你的症状,我假设你正在使用bash,你只能在序列表达式中使用文字(例如{1..3});从manual(强调我的):

Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result.

换句话说:在评估大括号表达式时,尚未扩展(解析)变量引用;因此,将$var1和$var2等文字解释为序列表达式上下文中的数字会失败,因此大括号表达式被视为无效且未展开.

但请注意,变量引用是扩展的,即在整体扩展的后期阶段;在手边的情况下,字面结果是单个单词'{1..4}’ – 展开变量值的未展开大括号表达式.

虽然括号扩展的列表形式(例如,{foo,bar))以相同的方式扩展,但后来的变量扩展在那里不是问题,因为不需要预先解释列表元素;例如{$var1,$var2}正确导致2个单词1和4.

至于为什么变量不能用于序列表达式:历史上,括号扩展的列表形式首先出现,当后来引入序列表达形式时,扩展的顺序已经固定.

有关支架扩展的一般概述,请参阅this answer.

解决方法

注意:变通方法的重点是数字序列表达式,如问题所示;基于eval的变通方法还演示了如何使用不太常见的字符序列表达式的变量,这些表达式产生英文字母范围(例如,{a..c}以产生b c).

一个小小的警告是seq不是POSIX实用程序,但大多数现代的类Unix平台都有它.

要稍微改进一下,使用seq的-f选项提供printf样式的格式字符串,并演示两位数的零填充:

seq -f '%02.f.txt' $var1 $var2 | xargs ls # '%02.f'==zero-pad to 2 digits, no decimal places

请注意,要使其完全健壮 – 如果生成的单词包含空格或制表符 – 您需要使用嵌入式引用:

seq -f '"%02.f a.txt"' $var1 $var2 | xargs ls

然后看到01 a.txt,02 a.txt,…正确保留了参数边界.

如果你想首先在Bash数组中稳健地收集结果单词,例如${words [@]}:

IFS=$'\n' read -d '' -ra words <

ls "${words[@]}"

以下是纯Bash解决方法:

使用Bash功能的有限解决方法是使用eval:

var1=1 var2=4

# Safety check

(( 10#$var1 + 10#$var2 || 1 )) 2>/dev/null || { echo "Need decimal integers." >&2; exit 1; }

ls $(eval printf '%s\ ' "{$var1..$var2}.txt") # -> ls 1.txt 2.txt 3.txt 4.txt

您可以将类似的技术应用于字符序列表达式;

var1=a var2=c

# Safety check

[[ $var1 == [a-zA-Z] && $var2 == [a-zA-Z] ]] || { echo "Need single letters."; exit 1; }

ls $(eval printf '%s\ ' "{$var1..$var2}.txt") # -> ls a.txt b.txt c.txt

注意:

>预先执行检查以确保$var1和$var2包含十进制整数或单个英文字母,这样可以安全地使用eval.通常,使用带有未经检查的输入的eval是一种安全风险,因此最好避免使用eval.

>鉴于eval的输出必须在此处不加引号传递给ls,以便shell通过单词拆分将输出拆分为单个参数,这仅在生成的文件名不包含嵌入空格或其他shell元字符时才有效.

一个更强大但更麻烦的纯Bash解决方法,使用数组创建等效的单词:

var1=1 var2=4

# Emulate brace sequence expression using an array.

args=()

for (( i = var1; i <= var2; i++ )); do

args+=( "$i.txt" )

done

ls "${args[@]}"

>此方法不存在安全风险,也适用于带有嵌入式shell元字符(如空格)的结果文件名.>可以通过将i替换为例如i = 2来以2为增量步长来实现自定义增量.>实现零填充需要使用printf;例如,如下:args =(“$(printf’?d.txt’”$i“)”)# – > ’01 .txt’,’02 .txt’,…

转载地址:http://irqhp.baihongyu.com/

你可能感兴趣的文章
html阴影效果怎么做,css 内阴影怎么做
查看>>
宏观经济
查看>>
综合练习:词频统计
查看>>
BZOJ1026: [SCOI2009]windy数
查看>>
样板操作数
查看>>
64位UBUNTU下安装adobe reader后无法启动
查看>>
iTextSharp带中文转换出来的PDF文档显示乱码
查看>>
组件:slot插槽
查看>>
走进C++程序世界------异常处理
查看>>
Nginx配置文件nginx.conf中文详解(转)
查看>>
POJ 1308 Is It A Tree?(并查集)
查看>>
N进制到M进制的转换问题
查看>>
利用sed把一行的文本文件改成每句一行
查看>>
Android应用开发:核心技术解析与最佳实践pdf
查看>>
python——爬虫
查看>>
孤荷凌寒自学python第五十八天成功使用python来连接上远端MongoDb数据库
查看>>
求一个字符串中最长回文子串的长度(承接上一个题目)
查看>>
简单权限管理系统原理浅析
查看>>
springIOC第一个课堂案例的实现
查看>>
求输入成绩的平均分
查看>>