截断星号得到的变量时抑制壳膨胀



在我的文件夹中,我有以下文件:

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 以获得所需的输出?

如果分配给数组,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 '%sn' "${d[@]%/}"

关于避免不必要的扩展 - 请注意,在上面,除了简单(字符串,而不是数组(赋值右侧的扩展之外,每个扩展都用双引号引起来。(常规赋值隐式地抑制了字符串拆分和 glob 扩展 - 尽管即使这样使用引号也没有什么坏处!这种抑制是${d:0:-1}从 glob 表达式本身而不是从其结果中删除/的原因(。

问题的答案

如果您愿意,您可以报价以避免$d*的扩展......

d=roi_${iroi}_*/
d2="${d:0:-1}"
echo $d2

。但是你可以直接写...

d2="roi_${iroi}_*"
echo $d2

。并且输出仍将与您的问题相同。

对预期输出的答复

您可以在阵列中进行扩展并选择第一个阵列条目,然后从该条目中删除/

for iroi in {1..116}; do
d=(roi_"$iroi"_*/)
d2="${d[0]:0:-1}"
echo "$d2"
done

这仅匹配目录并打印第一个不带尾随/的目录。

最新更新