I know how to extract a string by removing a prefix or suffix, but I don't know how to do both. Concretely, in the example below, how can I display inside my for-loop the names without a_ and _b?
$ touch a_cat_b a_dog_b a_food_b
$ for i in * ; do echo $i without a_ is ${i##a_} ;done;
a_cat_b without a_ is cat_b
a_dog_b without a_ is dog_b
a_food_b without a_ is food_b
$ for i in * ; do echo $i without _b is ${i%_b} ;done;
a_cat_b without _b is a_cat
a_dog_b without _b is a_dog
a_food_b without _b is a_food
CodePudding user response:
You can use the =~
operator:
#!/bin/bash
for f in *; do
if [[ $f =~ ^a_(.*)_b$ ]]; then
echo "$f without leading a_ and trailing _b is ${BASH_REMATCH[1]}"
fi
done
CodePudding user response:
Use parameter expansion to select just the middle of the string?
for i in a_cat_b a_dog_b a_food_b; do
printf "%s minux prefix and suffix is: %s\n" "$i" "${i:2:-2}"
done
${i:2-2}
is the substring starting with the third (0-based indexes) character of $i
, stopping at 2 before the end of the string.
This does assume the text you want to strip is fixed-length, of course.
CodePudding user response:
With bash
and a regex:
for i in *; do
if [[ $i =~ ^([^_]*)_(.*)_([^_]*)$ ]]; then
declare -p BASH_REMATCH
fi
done
Output:
declare -ar BASH_REMATCH=([0]="a_cat_b" [1]="a" [2]="cat" [3]="b") declare -ar BASH_REMATCH=([0]="a_dog_b" [1]="a" [2]="dog" [3]="b") declare -ar BASH_REMATCH=([0]="a_food_b" [1]="a" [2]="food" [3]="b")
CodePudding user response:
If a_
and _b
can only possibly match the start and the end of the string respectively then you can also do:
#!/bin/bash
shopt -s extglob
for f in a_cat_b a_dog_b a_food_b
do
echo "${f//@(a_|_b)}"
done
cat
dog
food