How to rename multiple files in several folders?
There are a thousand ways to do it, I'd do it with Perl, something like this will work:
find files -type f -name "file*" | perl -ne 'chomp; $f=$_; $f=~s/\/file/\/doc/; `mv $_ $f`;'
-ne
process as inline script for each line inputchomp
clean a newline$f
is new filename, same as old filenames/\/file/\/doc/
replace "/file" with "/doc" in the new filenamemv $_ $f
rename the file by running an OS command with back ticks
Ubuntu: Rename multiple files in different directory
If you run this command, it will use GNU Parallel to start a new bash
shell in each of the directories in parallel, and run ls
in each one in parallel independently:
parallel --dry-run -k 'cd {} && ls' ::: */
Sample Output
cd Dir01/ && ls
cd Dir02/ && ls
cd Dir78/ && ls
If you remove the --dry-run
it will do it for real.
So, instead of running ls
, let's now look at using the rename
command in each of the directories. The following will rename all the files in a directory with sequentially increasing numbers ($N
):
rename --dry-run '$_=$N' *
Sample Output
'file87' would be renamed to '1'
'file88' would be renamed to '2'
'file89' would be renamed to '3'
'fred' would be renamed to '4'
All the foregoing suggests the command you want would be:
parallel --dry-run -k 'cd {} && rename --dry-run "s/.*/{#}_\$N/" *' ::: */
You can run it as it is and it will just show you what it is going to do, without actually doing anything.
If you like the look of that, remove the first --dry-run
and run it again and it will actually go into each subdirectory and do a dry-run of the rename, again without actually changing anything.
If you still like the look of the command, make a small copy of your files somewhere in a temporary directory and try removing both the --dry-run
parameters ands if it lives up to your needs.
Batch copy and rename multiple files in the same directory
There are going to be a lot of ways to slice-n-dice this one ...
One idea using a for
loop, printf
+ brace expansion, and xargs
:
for f in 01*.sh
do
printf "%s\n" {02..05} | xargs -r -I PFX cp ${f} PFX${f:2}
done
The same thing but saving the printf
in a variable up front:
printf -v prefixes "%s\n" {02..05}
for f in 01*.sh
do
<<< "${prefixes}" xargs -r -I PFX cp ${f} PFX${f:2}
done
Another idea using a pair of for
loops:
for f in 01*.sh
do
for i in {02..05}
do
cp "${f}" "${i}${f:2}"
done
done
Starting with:
$ ls -1 0*.sh
01a_AAA_qwe.sh
01b_AAA_asd.sh
01c_AAA_zxc.sh
01d_AAA_rty.sh
All of the proposed code snippets leave us with:
$ ls -1 0*.sh
01a_AAA_qwe.sh
01b_AAA_asd.sh
01c_AAA_zxc.sh
01d_AAA_rty.sh
02a_AAA_qwe.sh
02b_AAA_asd.sh
02c_AAA_zxc.sh
02d_AAA_rty.sh
03a_AAA_qwe.sh
03b_AAA_asd.sh
03c_AAA_zxc.sh
03d_AAA_rty.sh
04a_AAA_qwe.sh
04b_AAA_asd.sh
04c_AAA_zxc.sh
04d_AAA_rty.sh
05a_AAA_qwe.sh
05b_AAA_asd.sh
05c_AAA_zxc.sh
05d_AAA_rty.sh
NOTE: blank lines added for readability
Renaming files in a folder to sequential numbers
Try to use a loop, let
, and printf
for the padding:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
using the -i
flag prevents automatically overwriting existing files, and using --
prevents mv
from interpreting filenames with dashes as options.
Rename multiple files in shell
I like mmv for this kind of thing
mmv 'linux_*' '#1'
But you can also use rename
. Be aware that there are commonly two rename
commands with very different syntax. One is written in Perl, the other is distributed with util-linux, so I distinguish them as "perl rename" and "util rename" below.
With Perl rename:
rename 's/^linux_//' linux_*.mp4
As cweiske correctly pointed out.
With util rename:
rename linux_ '' linux_*.mp4
How can you tell which rename you have? Try running rename -V
; if your version is util rename it will print the version number and if it is perl rename it will harmlessly report and unknown option and show usage.
If you don't have either rename
or mmv
and don't want to or can't install them you can still accomplish this with plain old shell code:
for file in linux_*.mp4 ; do mv "$file" "${file#linux_}" ; done
This syntax will work with any POSIX sh conforming to XPG4 or later, which is essentially all shells these days.
Related Topics
Mq Explorer - Could Not Load Swt Library
Different Show Between "Cat" and "Vim"
Libnetfilter_Queue Programming, How to Know Which Program Send The Packet
What's The Relation Between 32/64-Bit Application, Os and Processor
Why Is This Int $0X10 Bios Int Not Working on Linux
Shell: What Is The Purpose of ${Var:-} When Var Is Unset or Null
How to Overwrite Linux System Files into The Yocto Filesystem
Different Pulic Key for Jump Host and Destination Host Over Ssh
How to Generate Multiple Ssh Public Key and Configure Those on Windows Machine from Gitbash
Command Execution with Nohup in Background
Copying Local Git Config into Docker Container
Linux Grep/Sed Certain Lines - Space Removal