0

I have folders with album year and a bunch of text I don't care about and want removed/renamed. Here is what I was trying for the below files:

Calvin Harris - This Is What You Came For (2016) [MP3-320]

rename 's/(*//g' *

I'm getting the below error:

Unterminated '(*...' construct in regex; marked by <-- HERE in m/(* <-- HERE / at line 1, in: s/(*//g

I know I must be having issues with special characters. How can I rename everything after the '(' character so it would look something like this:

Calvin Harris - This Is What You Came For

Raffa
  • 32,237

2 Answers2

2

With shell parameter expansion in Bash and mv in a for ... loop:

for f in */; do [ -d "${f/ (*/}" ] || echo mv -nv -- "$f" "${f/ (*/}"; done

... where */ will only expand to directories (not files) and [ -d "${f/ (*/}" ] || will prevent moving into other directories which name matches the target new name if they exist and it will also prevent mv trying to move directories into sub-directories under themselves and thus forcing a renaming action only.

Notice echo is for a safe dry-run, and you need to remove it when satisfied with the output for actual renaming to happen ... Please, see demonstration below:

$ ls
'Calvin Harris - This Is What You Came For (2016) [MP3-320]'
$
$ for f in */; do [ -d "${f/ (*/}" ] || mv -nv -- "$f" "${f/ (*/}"; done
renamed 'Calvin Harris - This Is What You Came For (2016) [MP3-320]' -> 'Calvin Harris - This Is What You Came For'
$
$ ls
'Calvin Harris - This Is What You Came For'
Raffa
  • 32,237
1

To force a special character to be treated as a literal character in regex, you can escape it \( or place it inside a bracket expression [(].

However, \(* would match a sequence of zero or more ( characters. What you seem to want is to match a single ( followed by zero or more arbitrary characters, which would be \(.* or [(].*. If you also want to remove the leading space character, then it would be \(.*. So

$ rename -n 's/ \(.*//' -- *
rename(Calvin Harris - This Is What You Came For (2016) [MP3-320], Calvin Harris - This Is What You Came For)

If you were trying to rename files then bear in mind this would also remove any filename extension. So instead, you might want to match zero or more non-] characters followed by \] either

rename -n 's/ \([^]]*\]//' -- *

or (perhaps more aesthetically pleasing)

rename -n 's/ [(][^]]*[]]//' -- *

Note that the g global replacement flag is not necessary here, since you are making only a single replacement per file.

steeldriver
  • 136,215
  • 21
  • 243
  • 336
  • 1
    @KyloRen sorry I should have mentioned the -n is for testing - remove it when you're happy with the actions proposed – steeldriver Nov 11 '23 at 02:58