micholeodon
micholeodon

Reputation: 85

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?

Upvotes: 0

Views: 48

Answers (2)

Socowi
Socowi

Reputation: 27205

Answer to Question

If you wanted, you could quote to avoid expansion of * in $d ...

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

... but then you could directly write ...

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

... and the output would still be the same as in your question.

Answer to Expected Output

You could do the expansion in an array and select the first array entry, then remove the / from that entry.

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

This matches only directories and prints the first directory without the trailing /.

Upvotes: 0

Charles Duffy
Charles Duffy

Reputation: 295335

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).

Upvotes: 2

Related Questions