我正在尝试使用从变量到数组的内部 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 髑髅地,不工作什么都不会扩展,路径被拆分。
现在使用相同的路径包含空格但没有 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 或大括号扩展在变量内工作?
为什么当有空间时这不再起作用。完全相同的代码,但只是一个空格。球体或大括号扩展需要在双引号之外。评估似乎没有任何效果。
是否有任何其他替代方法可以使用(作为读取或映射文件,或者是否可以转义空格字符(?
我发现了这个问题 如何分配一个球体表达式 到一个变量 在 bash-脚本中,但没有关于空格的信息。
有没有办法将包含 glob 或大括号扩展参数的变量扩展到数组,当它们包含空格时,使用相同的方法而不进行单词拆分?
亲切问候
不要使用eval
.不要使用子外壳。只是清除IFS
.
path='./tmp2/tmp2 3/*'
oIFS=${IFS:-$' tn'} IFS='' # backup prior IFS value
expanded=( $path ) # perform expansion, unquoted
IFS=$oIFS # reset to original value, or an equivalent thereto
执行不带引号的扩展时,将按顺序发生两个单独的操作:
- 在
$IFS
变量中找到的所有字符都用于将字符串拆分为单词 - 然后,每个单词都扩展为一个单独的 glob。
默认值IFS
包含空格、制表符和换行符。如果您不希望将空格、制表符和换行符视为单词之间的分隔符,则需要修改该默认值。