Search code examples
bashshellvariable-expansion

Surpressing shell expansion when truncating variable obtained by asterisk


In my folder I have following files:

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

I use following script to obtain a desired prefix of the filename for each of all 116 types:

for iroi in `seq 1 116`;
do
    d=roi_${iroi}_*/
    d2=${d:0:-1}         # <-- THIS LINE IS IMPORTANT
    echo $d2
done;

Desired output for iroi=1:

$ roi_1_Precentral_L

Actual output:

$ 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

How can I avoid shell expansion in the emphasized line of code to make desired output?


Solution

  • If you assign to an array, the glob will be expanded on the first line, not later as of the echo as was the case with your original code.

    d=( "roi_${iroi}_"*/ )
    d2=${d:0:-1}            # Note that this only works with new bash. ${d%/} would be better.
    echo "$d2"
    

    If you expect multiple directories, "${d[@]%/}" will expand to the full list, with the trailing / removed from each:

    d=( "roi_${iroi}_"*/ )
    printf '%s\n' "${d[@]%/}"
    

    With respect to avoiding unwanted expansions -- note that in the above, every expansion except for those on the right-hand side of a simple (string, not array) assignment is in double quotes. (Regular assignments implicitly inhibit string-splitting and glob expansion -- though it doesn't hurt to have quotes even then! This inhibition is why ${d:0:-1} was removing the / from the glob expression itself, not from its results).