You either need to use xargs
or you need to use find
's ability to execute commands:
find -name "*_(*)." -type f | xargs rename 's/)././g'
find -name "*_(*." -type f | xargs rename 's/_(//g'
Or:
find -name "*_(*)." -type f -exec rename 's/)././g' {} +
find -name "*_(*." -type f -exec rename 's/_(//g' {} +
In both cases, the file names are added to the command line of rename
. As it was, rename
would have to read its standard input to discover the file names — and it doesn't.
Does the first find
find the files you want? Is the dot at the end of the pattern needed? Do the regexes do what you expect? OK, let's debug some of those too.
You could do it all in one command with a more complex regex:
find . -name "*_(*)" -type f -exec rename 's/_\((\d+)\)$/$1/' {} +
The find
pattern is corrected to lose the requirement of a trailing .
. If the _(x)
is inserted before the extension, then you'd need "*_(*).*"
as the pattern for find
(and you'll need to revise the Perl regexes).
The Perl substitute needs dissection:
- The
\(
matches an open parenthesis. - The
(
starts a capture group. - The
\d+
looks for 'one or more digits'. - The
)
stops the capture group. It is the first and only, so it is given the number 1. - The
\)
matches a close parenthesis. - The
$
matches the end of the file name. - The
$1
in the replacement puts the value of capture group 1 into the replacement text.
In your code, the 2>&1
sent the error messages from the second rename
command to standard output instead of standard error. That really doesn't help much here.
You need two separate tutorials; you are not going to find one tutorial that covers I/O redirection in Bash and regular expressions in Perl.
The 'official' Perl regular expression tutorial is:
- perlretut, also available as
perldoc perlretut
on your machine.
The Bash manual covers I/O redirection, but it is somewhat terse: