rename files with changing pattern - bash

i want to rename different files in bash with pattern and found this option:
rename 's/.2007/(2007)/g' *.*
with this pattern I can rename every file with ".2007" in name to "(2007)"
--> this is exactly what i want to do.
Next step:
i want to automate this, because i have files with 1995 - 2017. It is a possibility to do:
rename 's/.2007/(2007)/g' *.*
rename 's/.2008/(2008)/g' *.*
rename 's/.2009/(2009)/g' *.*
etc.
but actually, is there another solution?
my files are named like (they are not the same length...):
FILENAME.ANOTHERFILENAME.2007.jpg
FILENAME.2007.jpg
FILENAME.ANOTHERFILENAME.SOMETIMESONEMORE.2007.jpg

With Perl‘s rename:
rename -n 's/.([1-2][0-9]{3})/($1)/' *.*
This renames all files with 1000 to 2999. If everything looks fine remove -n.

For the use-cases where it's not so much about automation but rather about batch processing of a set of files, I find renameutils and its qmv ("quick move") very useful: it enables you to edit the target filenames in a text editor which may be easier/faster than designing regex's for some.
https://www.nongnu.org/renameutils/ (it's in *buntu repos)
But for applications that need to run w/o human intervention, rename is certainly more suitable.

Related

Batch file to rename files to specific names

So a quick explanation. We have hundreds of projects and in each of them and in every new project we have a program where we fill in a ton of information. From that we get 20 pdf files that are called File_1, File_2 etc.
What I'd like to do is to rename the files as the example below with a bat file.
File_1 = abc.pdf
File_2 = xyz.pdf
File_3 = qwe.pdf
I want to specific in the bat file what I want file_1 should be called and file_2 etc. The files I get will always be called File_1, File_2 etc and I always want them to be renamed the same. So each time I get those files I just run the bat file. Is there a way to do this? Or is there a better way to do this?
Thanks!
I'm assuming your files will always be called "file_1", "file_2" etc.??
If they are, then you can just write a file with a line for each file. For example
ren file_1 foo.pdf
ren file_2 bar.pdf
ren file_3 foobar.pdf
Note that as you didn't specify extensions for the original filenames, I haven't either. You would want to put the full file name with extension, or use wildcards if appropriate, e.g. ren file_1.*. (Be very careful with wildcards though, or you may end up trying to rename multiple files with the same name!)
You could check if the file exists first, and only run the ren on files that are there, or you could run it and let it error for missing files (though I'm sure other people will have reasons why you shouldn't).
You should also consider whether or not there will already be a file with the name you are trying to rename to, because if there the is then the rename will error and fail.
If your files will be different names daily, you will need to give more information as to what you have and what you need.
EDIT - Response to comment below
Copy (and complete) this code, and save it as 'rename.bat' or whatever you need.
#echo off
ren file_1 abc.pdf
ren file_2 xyz.pdf
ren file_3 qwe.pdf
<<repeat as necessary>>
The #echo off just stops the batch file from displayed the commands. It will still display errors (if the file doesn't exist or if you try to rename a file to an existing filename). You really should be looking at catching the errors and doing something with it, but if you can be 100% certain that the new filenames don't exist it will work.
Also worth pointing out that as I haven't used full file names, the batch file would need to be in the same folder as your file_1, file_2 etc.
You could use move to specify the full path of the original file, and a new path (it will move and rename the files), but you still have potentially the same problems with duplicate filenames etc.
I'm assuming you will end up with a folder containing file_1, file_2 etc. so you can just copy your batch file into the folder, run it, then move all your renamed files to where they need to go. Then next time you need to run the file, your folder would only have in it the new set of file_1, file_2 etc. so you could copy in the batch file again, run it... and so on.
EDIT2 - After thought for filenames including spaces
It just occurred to me that your existing files (file_1, file_2 etc.) don't appear to have any spaces in the name, but your new filenames might (you didn't specify the names exactly). If you have spaces if filenames, make sure to add quotes to the command e.g.
ren file_1 "my new file.pdf"
You can also quote your original filenames too (quoting both wouldn't hurt even if there are no spaces) so you could try
ren "file_1" "abc.pdf"
ren "file_2" "x y z.pdf"
ren "file_3" "qw e.pdf"
etc.

How to match numbering of files across different folders e.g. rename NAME9.txt to NAME00009.txt

I have a huge list of files, they came through different processes, so for some reason the ones in the first folder are numbered like this
A9.txt A1.txt while the ones in the other have A00009.txt A.00001.txt
I have no more than 99837 files so only four "extra" 0 on one side.
I need to rename all the files inside one folder so the names matches. Is there any way to do this in a loop? Thanks for the help.
You should take a look at perl-rename (Sometimes called rename) Not to be confused with rename from util-linux.
perl-rename 's/\d+/sprintf("%05d", $&)/e' *.txt
The above script will rename all .txt files in a directory to the following:
A1.txt -> A00001.txt
A10.txt -> A00010.txt
Hello225.txt -> Hello00225.txt
Test it Online

I want to change names Folders

i have Folders I want something to change the Folders names
nameFolders
nameFolders
nameFolders
nameFolders
i want to change the names of Folders to the serial numbers
1nameFolders
2nameFolders
3nameFolders
4nameFolders
Welcome to stackoverflow, please read: How to create a Minimal, Complete, and Verifiable example.
There is no explicit command for renaming files, however mv can be used to acomplish same goal, you could write mv file1 file1_renamed and rename file1 into file1_renamed.

Excluding directories using wildcards

I using xcopy, and I am trying to exclude directories with specific ending name from copying.
I've put the bellow line in exclude_files.txt to ignore those directories:
\\\*_bkup\\
Also, the xcopy command is the one bellow:
xcopy "C:\localfolder" "\\\server\remotefolder" /E /exclude:exclusion_list.txt
Only that it just doesn't ignore those directories.
What would the workaround be? I need it to ignore these directories in all of the tree's structure, not only in the root.
The /EXCLUDE option does not use wild cards in the masks. Use _bkup\ instead, without the wildcard.
But really you should be using ROBOCOPY instead. It may take a bit more study to figure it out, but it is much more powerful and precise.

Recursively copy file-types from directory tree

I'm trying to find a way to copy all *.exe files (and more, *.dtd, *.obj, etc.) from a directory structure to another path.
For example I might have:
Code
\classdirA
\bin
\classA.exe
\classdirB
\bin
\classB.exe
\classdirC
\bin
\classC.exe
\classdirD
\bin
\classD.exe
And I want to copy all *.exe files into a single directory, say c:\bins
What would be the best way to do this?
Constraints for my system are:
Windows
Can be Perl, Ruby, or .cmd
Anyone know what I should be looking at here?
Just do in Ruby, using method Dir::glob :
# this will give you all the ".exe" files recursively from the directory "Code".
Dir.glob("c:/Code/**/*.exe")
** - Match all directories recursively. This is used to descend into the directory tree and find all files in sub-directories of the current directory, rather than just files in the current directory. This wildcard is explored in the example code.
* - Match zero or more characters. A glob consisting of only the asterisk and no other characters or wildcards will match all files in the current directory. The asterisk is usually combined with a file extension, if not more characters to narrow down the search.
Nice blog Using Glob with Directories.
Now to copy the files to your required directory, you need to look into the method, FileUtils.cp_r :
require 'fileutils'
FileUtils.cp_r Dir.glob("c:/Code/**/*.exe"), "c:\\bins"
I just have tested, that FileUtils.cp method will also work, in this case :
require 'fileutils'
FileUtils.cp Dir.glob("c:/Code/**/*.exe"), "c:\\bins"
My preference here is to use ::cp method. Because Dir::glob is actually collecting all the files having .exe extensions recursively, and return them as an array. Now cp method is enough here, now just taking each file from the array and coping it to the target file.
Why I am not liking in such a situation, the method ::cp_r ?
Okay, let me explain it here also. As the method name suggests, it will copy all the files recursively from the source to target directory. If there is a need to copy specific files recursively, then ::cp_r wouldn't be able to do this by its own power ( as it can't do selections by itself, which ::glob can do ). Thus in such a situation, you have to give it the specific file lists, it would then copy then to the target directory. If this is the only task, I have to do, then I think we should go with ::cp, rather than ::cp_r.
Hope my explanation helps.
From cmd command line
for /r "c:\code" %f in (*.exe) do copy "%~ff" "c:\bins"
For usage inside a batch file, double the percent signs (%% instead of %)
Windows shell (cmd) command:
for /r code %q in (*.exe) do copy "%q" c:\bin
Double the % characters if you place this in a batch file.

Resources