arrays - 为什么当包含空格时,从变量到数组的 glob 或大括号扩展是不可能的
问题描述
我正在尝试使用从变量到数组的内部 bash glob 和大括号扩展机制。
path='./tmp2/tmp23/*'
expanded=($(eval echo "$(printf "%q" "${path}")"))
结果:
declare -- path="./tmp2/tmp23/*"
declare -a expanded=([0]="./tmp2/tmp23/testfile" [1]="./tmp2/tmp23/testfile2" [2]="./tmp2/tmp23/testfile3" [3]="./tmp2/tmp23/testfile4" [4]="./tmp2/tmp23/tmp231")
这是有效的。(我在 ./tmp2/tmp23 文件夹中有 4 个文件 testfileX 和 1 个文件夹)数组索引中的每个文件/文件夹。
现在,如果我的路径包含空格:
path='./tmp2/tmp2 3/*'
expanded=($(eval echo "$(printf "%q" "${path}")"))
结果
declare -- path="./tmp2/tmp2 3/*"
declare -a expanded=([0]="./tmp2/tmp2" [1]="3/")
由于IFS calvary,没有任何工作被扩展并且路径被分割。
现在具有包含空格但没有 glob 的相同路径:
path='./tmp2/tmp2 3/'
expanded=($(eval echo "$(printf "%q" "${path}"*)")) => added glob here outside ""
结果:
declare -a expanded=([0]="./tmp2/tmp2" [1]="3/testfile./tmp2/tmp2" [2]="3/testfile2./tmp2/tmp2" [3]="3/testfile3./tmp2/tmp2" [4]="3/testfile4./tmp2/tmp2" [5]="3/tmp231")
路径已扩展,但由于 IFS,结果为错误且分裂。
现在引用 $(eval)
expanded=("$(eval echo "$(printf "%q" "${path}"*)")")
结果:
declare -a expanded=([0]="./tmp2/tmp2 3/testfile./tmp2/tmp2 3/testfile2./tmp2/tmp2 3/testfile3./tmp2/tmp2 3/testfile4./tmp2/tmp2 3/tmp231")
现在所有扩展都在同一个数组索引内完成。
如果没有空格,为什么 glob 或大括号扩展在变量内部起作用?
为什么当有空间时这不再起作用了。完全相同的代码,但只是一个空格。大括号或大括号扩展需要在双引号之外。eval 似乎没有效果。
是否有其他替代方法可以使用(作为读取或映射文件,或者是否可以转义空格字符)?
我发现了这个问题how-to-assign-a-glob-expression-to-a-variable-in-a-bash-script但没有关于空格的问题。
有没有办法使用相同的方法将包含带空格或不带空格的 glob 或大括号扩展参数的变量扩展为数组,当它们包含空格时不进行分词?
亲切的问候
解决方案
不要使用eval
. 不要使用子shell。只要清楚IFS
。
path='./tmp2/tmp2 3/*'
oIFS=${IFS:-$' \t\n'} IFS='' # backup prior IFS value
expanded=( $path ) # perform expansion, unquoted
IFS=$oIFS # reset to original value, or an equivalent thereto
当您执行不带引号的扩展时,会按顺序发生两件不同的事情:
- 在变量中找到的所有字符
$IFS
都用于将字符串拆分为单词 - 然后将每个单词扩展为一个单独的 glob。
的默认值IFS
包含空格、制表符和换行符。如果您不希望将空格、制表符和换行符视为单词之间的分隔符,则需要修改该默认值。
推荐阅读
- c++ - C++ 检查十六进制是否由 ABCDEF1 或 0 组成
- mysql - 带有AUTO_INCREMENT主键的Mysql主从复制
- facebook - facebook 中的画布和顶部导航栏
- c# - 适合 TLS 1.2 的密码
- vba - VBA 将复选框包含到用户表单中,根据表值选中/取消选中
- javascript - 打开自定义创建的 .ics 文件时,Iphone 中 safari 的奇怪行为
- ruby-on-rails - 带有关联 has_many -> belongs_to 的 Ruby 未定义方法“错误”
- android - 按下按钮后插播广告不显示
- php - PHP测验无法正常工作
- c++ - 基于 C++ 范围的 for 循环