2

Basically, I'm trying to increment each digit in _XtoX of each file below by 20

err_5JUP_N2_UUCCGU_1to2  err_5JUP_N2_UUCCGU_3to4  err_5JUP_N2_UUCCGU_5to6  err_5JUP_N2_UUCCGU_7to8  err_5JUP_N2_UUCCGU_9to10

such that the new file names should look like such:

err_5JUP_N2_UUCCGU_21to22  err_5JUP_N2_UUCCGU_23to24  err_5JUP_N2_UUCCGU_25to26  err_5JUP_N2_UUCCGU_27to28  err_5JUP_N2_UUCCGU_29to30

I came up with the following snippet of code:

for FILE in err*
do
    mv $FILE ${FILE/$"_"*to*/"_$((*+20))to$((*+20))}
done 

I essentially identified the pattern with "_"*to*/, but I'm pretty sure the * is not a reasonable way to capture the values and increment them. What is an alternative solution to this?

2
  • Look up the documentation for BASH_REMATCH, which is populated by [[ $string =~ $regex ]]. Ensure that all the content you want to reuse unchanged is included in match groups (distinct from the groups collecting content to use as input to calculate new values), and then it's easy to construct a new string from those groups. Commented Jun 12, 2023 at 15:22
  • Can you use the perl-based rename command? It can do this pretty easily using the e modifier in s///. This will be much easier than trying to do it using bash built-ins. Commented Jun 12, 2023 at 15:28

1 Answer 1

2

Try this Shellcheck-clean code:

#! /bin/bash -p

shopt -s extglob nullglob

for errfile in err*_+([0-9])to+([0-9]); do
    n1ton2=${errfile##*_}
    n1=${n1ton2%to*}
    n2=${n1ton2#*to}
    new_errfile=${errfile%_*}_$((n1+20))to$((n2+20))
    echo mv -v -- "$errfile" "$new_errfile"
done
  • Remove the echo if you are happy that the code will do what you want.
  • shopt -s ... enables some Bash settings that are required by the code:
    • extglob enables "extended globbing" (including patterns like +([0-9])). See the extglob section in glob - Greg's Wiki.
    • nullglob makes globs expand to nothing when nothing matches (otherwise they expand to the glob pattern itself, which is almost never useful in programs).
  • See Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?)) for explanations of ${var##pat}, ${var%pat}, and ${var#pat}.
  • Note that ALL_UPPERCASE variable names (like FILE) are best avoided because there is a danger of clashes with the large number of special ALL_UPPERCASE variables that are used in shell programming. See Correct Bash and shell script variable capitalization. That's why I used errfile instead of FILE.
Sign up to request clarification or add additional context in comments.

9 Comments

First time I saw -p used in a shebang. Makes me wonder why Bash had to change the EUID by default.
@konsolebox, w.r.t. -p in the shebang, see the "Sanitizing the Environment in BASH" section of Shell Script Security - Apple Developer. Essentially, it's to reduce the risk of the program being broken by stuff in the user's environment.
Thank you so much! I'm very much new to regular expressions and bash scripting. I appreciate your help :)
@pjh Can you cite the important text? I doubt it's the environment. Read the Bash manual. It's about the EUID. The purpose of -p is to not change the EUID to real UID which seems the default behavior of Bash. This default behavior is questionable, that's why I wondered. I wasn't really asking about the purpose of -p or why it's helpful to place it in a shebang.
@konsolebox, (some versions of) the Bash manual page have incomplete and/or misleading and/or incorrect information about the -p option. The relevant (and correct) text from the Bash Reference Manual is: "-p : Turn on privileged mode. In this mode, the $BASH_ENV and $ENV files are not processed, shell functions are not inherited from the environment, and the SHELLOPTS, BASHOPTS, CDPATH and GLOBIGNORE variables, if they appear in the environment, are ignored."
|

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.