
Hi there, I have a bunch of files that I want to rename: 123.someword.doc > 123.doc 456.someword.pdf > 456.pdf The "someword" is consistent in all the files and they need to be renamed recursively. Something like this but with a different regex: # This is for a completely different file name structure find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_//}"' -- {} \; ...sorry regex is a shortfall of mine. Thanks in advance. Cheers Piers

https://www.maketecheasier.com/rename-files-in-linux/ On Fri, 15 Nov 2019 at 12:51, Piers via luv-main <luv-main@luv.asn.au> wrote:
Hi there,
I have a bunch of files that I want to rename:
123.someword.doc > 123.doc
456.someword.pdf > 456.pdf
The "someword" is consistent in all the files and they need to be renamed recursively.
Something like this but with a different regex:
# This is for a completely different file name structure
find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_//}"' -- {} \;
...sorry regex is a shortfall of mine.
Thanks in advance.
Cheers
Piers
_______________________________________________ luv-main mailing list luv-main@luv.asn.au https://lists.luv.asn.au/cgi-bin/mailman/listinfo/luv-main
-- Dr Paul van den Bergen

On Fri, Nov 15, 2019 at 11:51:40AM +1000, Piers wrote:
I have a bunch of files that I want to rename:
123.someword.doc > 123.doc
456.someword.pdf > 456.pdf
The "someword" is consistent in all the files and they need to be renamed recursively.
Use the perl-based 'rename' tool (which is sometimes in the PATH as 'prename' or 'file-rename' instead of just 'rename'). Note, this is **NOT** the same as the rename tool from util-linux (which has completely different command-line options and capabilities, and is sometimes called 'rename.ul'). On debian (and ubuntu, etc), 'apt-get install rename' if it isn't already installed (run 'man rename' to see if it mentions Perl). On other distros, install whatever package provides the perl File::Rename module. Anyway, the perl 'rename' allows you to use ANY perl code, from trivial sed-like search and replace to complex perl code blocks to rename files. e.g. i've written rename commands that sort files into sub-directories by the file's timestamp or name, convert them to TitleCase, change spaces to '_' or '.' (or just remove them), AND change their permissions - all in one command. But most of the time, I just need to do a regexp search and replace on the filenames. Like this: rename -n 's/\.someword//' *someword* NOTE: The '-n' is a dry-run, it shows you what would be renamed if you allowed it. To actually rename, get rid of the '-n' or replace it with '-v' for verbose output. BTW, rename won't overwrite existing files unless you force it to with '-f'. Perl rename can take a list of filenames on the command-line or from stdin, so you could do a recursive rename with either of these: find . -type f -name '*someword*' -exec rename -n 's/\.someword//' {} + find . -type f -name '*someword*' -print0 | rename -n -0 's/\.someword//'
Something like this but with a different regex:
# This is for a completely different file name structure
find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_//}"' -- {} \;
You really don't want to be forking 'bash' AND 'mv' once for each matching file. The following line tries to fit as many filenames on the command line as will fit (the command line length limit is typically around 2MB these days), so will almost always only run bash once. or maybe twice. as few times as necessary, anyway. find . -name '123*.txt' -type f -exec bash -c 'for f in "$@"; do mv "$f" "${1/\/123_//}"; done' -- {} + Note the use of '{} +' instead of '{} \;' - that's what makes 'find' try to fit as many filenames onto a command-line as possible each time the -exec option's command is executed. Unfortunately, this still forks 'mv' once for each filename, so it's still going to be slow. Even better, don't use bash at all, use the right tool for the job: find . -type f -name '123*.txt' -exec rename -n 's:/123_::' {} + Or, to pipe a NUL separated list of filenames (to avoid command-line length limits entirely): find . -type f -name '123*.txt' -print0 | rename -n -0 's:/123_:/:' (again, remove the '-n' or replace with '-v' to make it actually rename files once you've verified that it does what you want). craig -- craig sanders <cas@taz.net.au>

On Fri, 15 Nov 2019 at 12:51, Piers via luv-main <luv-main@luv.asn.au> wrote:
Hi there,
Hi
I have a bunch of files that I want to rename:
For a range of approaches, have a look here: http://mywiki.wooledge.org/BashFAQ/030
...sorry regex is a shortfall of mine.
There's no regex anywhere in your examples, only "globs" aka shell pattern matching aka shell pathname expansion. See here: http://mywiki.wooledge.org/glob http://mywiki.wooledge.org/RegularExpression It's important to understand that these are distinct things. They superficially might look similar, but they behave differently. regex is more powerful, and more complicated. A perl-based solution will require you to use regex notation. A solution using 'find' and 'mv' with shell parameter expansion (like your example) http://mywiki.wooledge.org/BashFAQ/073 will require you to use glob notation. So a first step might be to choose which of regex or glob you prefer, and then proceed from there. Your problem statement looks simple enough that regex is not required, unless you choose an approach that mandates using regex. Personally being already comfortable with both, I would probably use a perl-based "rename" tool. It has a dry-run option which is useful when you are unsure of the syntax.

On Fri, 15 Nov 2019 11:51:40 AM Piers via luv-main wrote: Hi, I solved my somewhat similar problem with pyrenamer. It may be exactly what is needed here too. Petr Baum _________________________________
Hi there,
I have a bunch of files that I want to rename:
123.someword.doc > 123.doc
456.someword.pdf > 456.pdf
The "someword" is consistent in all the files and they need to be renamed recursively.
Something like this but with a different regex:
# This is for a completely different file name structure
find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_//}"' -- {} \;
...sorry regex is a shortfall of mine.
Thanks in advance.
Cheers
Piers
_______________________________________________ luv-main mailing list luv-main@luv.asn.au https://lists.luv.asn.au/cgi-bin/mailman/listinfo/luv-main
-- <pb-luv@baum.com.au> Petr Baum, P.O.Box 2364, Rowville 3178 fax +61-3-97643342 This message was created in naturally virus-free operating system: Linux
participants (5)
-
Craig Sanders
-
David
-
Paul van den Bergen
-
Petr Baum
-
Piers