截取星号获取的变量时抑制shell扩展
Surpressing shell expansion when truncating variable obtained by asterisk
在我的文件夹中有以下文件:
roi_1_Precentral_L/
roi_1_Precentral_L_both.fig
roi_1_Precentral_L_left.fig
roi_1_Precentral_L_right.fig
roi_1_Precentral_L_slice.fig
roi_2_Precentral_R/
roi_2_Precentral_R_both.fig
...
roi_116_Vermis_10/
roi_116_Vermis_10_both.fig
roi_116_Vermis_10_left.fig
roi_116_Vermis_10_right.fig
roi_116_Vermis_10_slice.fig
我使用以下脚本为所有 116 种类型中的每一种获取所需的文件名前缀:
for iroi in `seq 1 116`;
do
d=roi_${iroi}_*/
d2=${d:0:-1} # <-- THIS LINE IS IMPORTANT
echo $d2
done;
iroi=1 的期望输出:
$ roi_1_Precentral_L
实际输出:
$ roi_1_Precentral_L roi_1_Precentral_L_both.fig roi_1_Precentral_L_left.fig roi_1_Precentral_L_right.fig roi_1_Precentral_L_slice.fig
如何避免 shell 扩展强调的代码行以获得所需的输出?
问题的答案
如果你愿意,你可以引用以避免在 $d
中扩展 *
...
d=roi_${iroi}_*/
d2="${d:0:-1}"
echo $d2
...但是你可以直接写...
d2="roi_${iroi}_*"
echo $d2
...输出仍然与您的问题相同。
预期输出的答案
您可以在数组中进行扩展,select 第一个数组条目,然后从该条目中删除 /
。
for iroi in {1..116}; do
d=(roi_"$iroi"_*/)
d2="${d[0]:0:-1}"
echo "$d2"
done
这只匹配目录并打印第一个目录,不带尾随 /
。
如果您分配给一个数组,glob 将在第一行展开,而不是像您的原始代码那样在 echo
之后展开。
d=( "roi_${iroi}_"*/ )
d2=${d:0:-1} # Note that this only works with new bash. ${d%/} would be better.
echo "$d2"
如果您希望有多个目录,"${d[@]%/}"
将扩展为完整列表,每个目录的尾部 /
将被删除:
d=( "roi_${iroi}_"*/ )
printf '%s\n' "${d[@]%/}"
关于避免不需要的扩展——请注意,在上面,每个扩展除了简单(字符串,而不是数组)赋值右侧的扩展是双引号。 (常规赋值隐含地禁止字符串拆分和 glob 扩展——尽管即使那样使用引号也没有坏处!这种抑制就是为什么 ${d:0:-1}
从 glob 表达式本身而不是从中删除 /
它的结果)。
在我的文件夹中有以下文件:
roi_1_Precentral_L/
roi_1_Precentral_L_both.fig
roi_1_Precentral_L_left.fig
roi_1_Precentral_L_right.fig
roi_1_Precentral_L_slice.fig
roi_2_Precentral_R/
roi_2_Precentral_R_both.fig
...
roi_116_Vermis_10/
roi_116_Vermis_10_both.fig
roi_116_Vermis_10_left.fig
roi_116_Vermis_10_right.fig
roi_116_Vermis_10_slice.fig
我使用以下脚本为所有 116 种类型中的每一种获取所需的文件名前缀:
for iroi in `seq 1 116`;
do
d=roi_${iroi}_*/
d2=${d:0:-1} # <-- THIS LINE IS IMPORTANT
echo $d2
done;
iroi=1 的期望输出:
$ roi_1_Precentral_L
实际输出:
$ roi_1_Precentral_L roi_1_Precentral_L_both.fig roi_1_Precentral_L_left.fig roi_1_Precentral_L_right.fig roi_1_Precentral_L_slice.fig
如何避免 shell 扩展强调的代码行以获得所需的输出?
问题的答案
如果你愿意,你可以引用以避免在 $d
中扩展 *
...
d=roi_${iroi}_*/
d2="${d:0:-1}"
echo $d2
...但是你可以直接写...
d2="roi_${iroi}_*"
echo $d2
...输出仍然与您的问题相同。
预期输出的答案
您可以在数组中进行扩展,select 第一个数组条目,然后从该条目中删除 /
。
for iroi in {1..116}; do
d=(roi_"$iroi"_*/)
d2="${d[0]:0:-1}"
echo "$d2"
done
这只匹配目录并打印第一个目录,不带尾随 /
。
如果您分配给一个数组,glob 将在第一行展开,而不是像您的原始代码那样在 echo
之后展开。
d=( "roi_${iroi}_"*/ )
d2=${d:0:-1} # Note that this only works with new bash. ${d%/} would be better.
echo "$d2"
如果您希望有多个目录,"${d[@]%/}"
将扩展为完整列表,每个目录的尾部 /
将被删除:
d=( "roi_${iroi}_"*/ )
printf '%s\n' "${d[@]%/}"
关于避免不需要的扩展——请注意,在上面,每个扩展除了简单(字符串,而不是数组)赋值右侧的扩展是双引号。 (常规赋值隐含地禁止字符串拆分和 glob 扩展——尽管即使那样使用引号也没有坏处!这种抑制就是为什么 ${d:0:-1}
从 glob 表达式本身而不是从中删除 /
它的结果)。