Renaming a file using regex and x = $ {...} in Bash?

I have a bunch of files containing prefix codes in brackets. I would like to turn these prefixes into suffixes, for example:

Finance-(4BF)-001.doc --> Finance-001-4BF.doc Corporate-(K04)-001.doc --> Corporate-001-K04.doc 

I previously wrote a very simple VBScript for this on a Windows machine, but now I need to do this on Linux. After some tedious searching, I can't find a simple and elegant way to apply a regular expression to a file name and rename it using regular expression matches.

So far I have this:

 #!/bin/bash for i in *.doc do x=${i//[\(\)]/} echo "$i renames to: $x" done 

The result of this:

 Corporate-(K04)-001.doc renames to: Corporate-K04-001.doc Finance-(4BF)-001.doc renames to: Finance-4BF-001.doc 

I know that the regular expression above just strips the brackets () from the file name ... but there certainly should be a way to match their contents (e.g. \((\w)\) ) and then use this match in rename command (e.g. $1 )?

Also, being a Linux newbie, I donโ€™t understand what x=${...} does, and since I donโ€™t know what he called, I cannot use it. I assume that it applies the regular expression to line i , but in this case why can't I extract matches from it like $1 and $2 , etc.

Thanks!

+4
source share
4 answers

The ${...} construct is called the "parameter extension" and can be found in the Bash manual.

The replacement function is very basic and does not support backlinks ( $1 ). You can use sed instead:

 x=$(sed -E 's/\(([[:alnum:]]+)\)-([[:alnum:]]+)/\2-\1/' <<< "$i") 

Note that [[:alnum:]] same as \w in other languages, but POSIX regular expressions do not have the latter. See man re_format more details.

+3
source

Syntax ${parameter/pattern/string} in a Bash parameter extension is not a regular expression; this is glob (especially c # and % ).

Bash has [[ =~ ]] conditional expressions with regular expressions that put the captured groups into the ${BASH_REMATCH[@]} array.

 #!/bin/bash for i in *.doc; do if [[ $i =~ ^(.*)-\((.*)\)-([^.]*)(..*)?$ ]]; then x="${BASH_REMATCH[1]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]}${BASH_REMATCH[4]}" echo "$i renames to: $x" fi done 
+3
source

Depending on the system you are using, there should be a rename utility, which is actually a perl script and allows you to use a regular expression. I know that in the new version of Ubuntu they have such a command, while in my Slackware distribution I do not have it.

However, you can try and use it as follows:

rename 's/-\((.{3})\)-(.{3})/-$2-$1/' *.doc

Otherwise, you should rely on sed or awk.

+3
source

Try the following:

 #!/bin/bash for i in *.doc; do x=${i#*(} x=${x%)*} echo "$i renames to: ${i%%-*}-$x-${i##*-}" done 
0
source

Source: https://habr.com/ru/post/1432796/


All Articles