Using rename to rename files and directories - linux

I'm using the Linux rename command line tool to search recursively through a directory to rename any directories as well as files it finds. The issue I'm running into is the rename command will rename a sub-directory of a file then attempt to rename the parent directory of the same file. This will fail because the sub-directory has been renamed resulting in a "No such file or directory"
Command:
rename -f 's/foo/bar/' **
rename -f 's/Foo/Bar/' **
For example, here is an original file that I would like to replace 'foo' with 'bar'
File:
/test/foo/com/test/foo/FooMain.java
Failure:
Can't rename /test/foo/com/test/foo/FooMain.java /test/bar/com/test/foo/FooMain.java: No such file or directory
Preferred File:
/test/bar/com/test/bar/BarMain.java
You can see from the error message that it's attempting to rename the parent directory but at that point the subdirectory has already been changed resulting in the file not found error. Is there parameters for the rename command that will fix this or do I need to go about this in a different way?

Use find + execdir option:
$ find . -execdir rename "s/foo/bar/" {} \;
$ find . -execdir rename "s/Foo/Bar/" {} \;

Related

How to rename all the files from a directory?

So, i have a given directory, and that directory contains other subdirectories, and every subdirectory can contain a file. I have to change all the files names, so that it will end in ".txt" .
**You can do something like this using bash : and go over all your directories with it **
for f in *.their_current_end;
do
mv -- "$f" "${f%.their_current_end}.txt"
done
another solution would be using : rename in Linux
rename [OPTIONS] perlexpr files
where the rename will rename all the files mentioned like the regex supplied in the perlexpr parameter.
example :
rename 's/.html/.php/' \*.html

linux command line subfolder files batch rename that actually works

In a folder with many subfolders, each containing mp4 files with names ending in foobar.mp4
How can I get rid of the suffix? I have tried:
find ./*/*.mp4 -type f -exec rename 's/foobar//' '{}' \;
On surface, there is no need to use 'find', as the rename command has the ability to process list of file. In particular, possible to write
rename 's/foobar//' */*foobar.mp4
It's not clear from the OP what are the actual file names. The above command will rename 'foobar.mp4' to hidden file '.mp4', and the file 'x.foobar.mp4' to 'x..mp4'.

How can I unzip files in Linux when other files are present

I have files such as these
a1.tif
a2.tif
a1.zip
sa.zip
ff.zip
wqqq.zip
I want to unzip only the zip files and ignore the .tif files
Also ignore those .zip files that have already been decompressed.
I am getting this
unzip /*zip
unzip: cannot find or open /*zip, /*zip.zip or /*zip.ZIP.
You are searching for anything in the root directory that ends with "zip". Use *.zip for any file in the current directory ending in ".zip", or more explicitly use ./*.zip, ./ being the current directory.
That said, if you have more than one match it will pass all of them to the unzip command with the first being interpreted as the archive file and the remaining matches as files to extract from the archive. Avoid this by using find to pass each match to unzip.
find . -name '*.zip' -exec unzip {} \;

Wrtie a script to Delete files if it exists in different folder in Linux

I'm trying write a script in linux. Where I have some csv files in Two different folders(A and B) and then after some processing copy of rejected files are moving to Bad Folder.
SO I want bad files to be deleted from Table A and B which have copied to Bad Folder.
Can you help me to write this script for linux?
Best
lets say name of Bad Folder is 'badFolder' and considering 'A', 'B' and 'badFolder' are in same directory
Steps to delete files from folder A and B:
step 1: change current directory to your 'badFolder'
cd badFolder
step 2: delete identical files
find . -type f -exec rm -f ../A/{} \;
find . -type f -exec rm -f ../B/{} \;
The argument -type f tells to look for files, not directories.
The -exec ... \; argument tells that, once it finds a file in 'badFolder', it should run the command rm -f on its counterpart in the A subdirectory.
Because rm is given with the -f option, it will silently ignore files that don't exist.
Also, it will not prompt before deleting files. This is very handy when deleting a large number of files. However, be sure that you really want to delete the files before running this script.
#!/bin/bash
#Set the working folder in which you want to delete the file
Working_folder=/<Folder>/<path>
cd $Working_folder
#command to delete all files present in folders
rm <filenames seperated by space>
echo "files are deleted"
#if you want to delete all files you can use wild card character
# e.g. command rm *.*
# if you want to delete a particular file say for deleting .csv file you can use command rm *.csv command
Set variables containing the paths of your A, B and BAD directories.
Then you can do something along the lines of
for file in ls ${PATH_TO_BAD}
do
rm ${PATH_TO_A}/$file
rm ${PATH_TO_B}/$file
done
This is iterating over the BAD directory and any file it finds, it deletes from the A and B directories.

Rename file in Linux if file exist in a single command

There is need that I want to rename file in Linux if file exist in a single command.
Suppose I want to search test.text file and I want to replace it with test.text.bak then I fire the following command
find / -name test.text
if it exist then I fire the command
mv test.text test.text.bak
In this scenario I am executing two commands but I want this should be happen in single command.
Thanks
Just:
mv test.text test.test.bak
If the file doesn't exist nothing will be renamed.
To supress the error message, when no file exits, use that syntax:
mv test.text test.test.bak 2>/dev/null
If you want to find test.txt somewhere in a subdirectory of dir and move it, try
find dir -name test.txt -exec mv {} {}.bak \;
This will move all files matching the conditions. If you want to traverse from the current directory, use . as the directory instead of dir.
Technically, this will spawn a separate command in a separate process for each file matched by find, but it's "one command" in the sense that you are using find as the only command you are actually starting yourself. (Think of find as a crude programming language if you will.)
for FILE in `find . -name test.test 2>/dev/null`; do mv $FILE $FILE.bak; done
This will search all the files named "test.test" in current as well as in child direcroties and then rename each file to .bak

Resources