0

I'm working on a bash script to rename automatically files on my Synology NAS.

I have a loop for the statement of the files and everything is ok until I want to make my script more efficient with regex.

I have several bits of code which are working like as expected:

filename="${filename//[-_.,\']/ }"
filename="${filename//[éèēěëê]/e}"

But I have this:

filename="${filename//t0/0}"
filename="${filename//t1/1}"
filename="${filename//t2/2}"
filename="${filename//t3/3}"
filename="${filename//t4/4}"
filename="${filename//t5/5}"
filename="${filename//t6/6}"
filename="${filename//t7/7}"
filename="${filename//t8/8}"
filename="${filename//t9/9}"

And, I would like to use captured group to have something like this:

filename="${filename//t([0-9]{1,2})/\1}"
filename="${filename//t([0-9]{1,2})/${BASH_REMATCH[1]}}"

I've been looking for a working syntax without success...

2
  • Please edit your question to include concise, testable sample input and expected output that covers all of your use-cases. In particular show what a filename like abt1cdt2eft3gh should end up looking like so we can be sure if you're trying to convert the first tN or last or all of them in a filename. Commented Aug 20, 2022 at 13:02
  • Also show what the output should be for a filename of abtt123de as the 2 answers you have so far would behave differently from each other. Commented Aug 20, 2022 at 13:18

2 Answers 2

2

The shell's parameter expansion facility does not support regular expressions. But you can approximate it with something like

filename=$(sed 's/t\([0-9]\)/\1/g' <<<"$filename")

This will work regardless of whether the first digit is followed by additional digits or not, so dropping that requirement simplifies the code.

Sign up to request clarification or add additional context in comments.

Comments

1

If you want the last or all t[0-9]{1,2}s replaced:

$ filename='abt1cdt2eft3gh'; [[ "$filename" =~ (.*)t([0-9]{1,2}.*) ]] && filename="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; echo "$filename"
abt1cdt2ef3gh

$ filename='abt1cdt2eft3gh'; while [[ "$filename" =~ (.*)t([0-9]{1,2}.*) ]]; do filename="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; done; echo "$filename"
ab1cd2ef3gh

Note that the "replace all" case above would keep iterating until all t[0-9]{1,2}s are changed, even ones that didn't exist in the original input but were being created by the loop, e.g.:

$ filename='abtt123de'; while [[ "$filename" =~ (.*)t([0-9]{1,2}.*) ]]; do filename="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; echo "$filename"; done
abt123de
ab123de

whereas the sed script in @tripleee's answer would not do that:

$ filename='abtt123de'; filename=$(sed 's/t\([0-9]\)/\1/g' <<<"$filename"); echo "$filename"
abt123de

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.