Find multiple files and rename them in Linux
I am having files like a_dbg.txt, b_dbg.txt . in a Suse 10 system. I want to write a bash shell script which should rename these files by removing «_dbg» from them. Google suggested me to use rename command. So I executed the command rename _dbg.txt .txt *dbg* on the CURRENT_FOLDER My actual CURRENT_FOLDER contains the below files.
CURRENT_FOLDER/a_dbg.txt CURRENT_FOLDER/b_dbg.txt CURRENT_FOLDER/XX/c_dbg.txt CURRENT_FOLDER/YY/d_dbg.txt
CURRENT_FOLDER/a.txt CURRENT_FOLDER/b.txt CURRENT_FOLDER/XX/c_dbg.txt CURRENT_FOLDER/YY/d_dbg.txt
Its not doing recursively, how to make this command to rename files in all subdirectories. Like XX and YY I will be having so many subdirectories which name is unpredictable. And also my CURRENT_FOLDER will be having some other files also.
13 Answers 13
You can use find to find all matching files recursively:
find . -iname "*dbg*" -exec rename _dbg.txt .txt '<>' \;
EDIT: what the ‘<>‘ and \; are?
The -exec argument makes find execute rename for every matching file found. ‘<>‘ will be replaced with the path name of the file. The last token, \; is there only to mark the end of the exec expression.
All that is described nicely in the man page for find:
-exec utility [argument . ] ; True if the program named utility returns a zero value as its exit status. Optional arguments may be passed to the utility. The expression must be terminated by a semicolon (``;''). If you invoke find from a shell you may need to quote the semicolon if the shell would otherwise treat it as a control operator. If the string ``<>'' appears anywhere in the utility name or the argu- ments it is replaced by the pathname of the current file. Utility will be executed from the directory from which find was executed. Utility and arguments are not subject to the further expansion of shell patterns and constructs.
Change Names of Multiple Files Linux
I have a number of files with names a1.txt, b1.txt, c1,txt. on ubuntu machine. Is there any quick way to change all file names to a2.txt, b2.txt, c2.txt. In particular, I’d like to replace part of the name string. For instance, every file name contains a string called «apple» and I want to replace «apple» with «pear» in all file names. Any command or script?
6 Answers 6
without any extra software you can:
for FILE in *1.txt; do mv "$FILE" $(echo "$FILE" | sed 's/1/2/'); done
for f in 1.txt; do echo "$f" "$"; done
replace ‘echo’ with ‘mv’ if the output looks correct.
and I want to replace «apple» with «linux»
for f in *apple*; do mv "$f" "$"; done
The curly brackets in line 1 should work with bash at least.
Well, first, I figured replacing linux with pear would be the more obvious fix as «apple»->»pear» is the example in the OP and pear was clearly the intent while linux was a copy/paste remnant. Second, your second command needs done affixed to the end otherwise it prompts for it. Third, while the curly braces do work, I find the * wildcard operator to be more widely applicable (which is the point on SO) and also more intuitive. (This third point is more of an opinion and you do use * in your second example, so I would be ok if you left your first command as is.)
Your idea to echo the files first to make sure of correct output before the actual action (Linux can be quite unforgiving of small typos/mistakes) makes this answer a bit better than the accepted I feel, but I don’t feel that I can support it unless it 1: does the same thing it claims to do (the linux/pear mix-up in your original answer) and 2: works immediately when copy/pasted as a command (which it requires the done to do)
@River:
How do I easily rename multiple files using command line?
But in Ubuntu/Nautilus, I can’t tab to next file. But being on Linux, I think there must be a command line alternative. However, sometimes, I may want more control over how to rename specific files. In that case, perhaps its better to be able to tab to the next file
I think this question is not answered. What you are asking for (F2 and then jump in F2 mode to the next file) is currently not available I think in Nautilus.
8 Answers 8
I use rename all the time. It is pretty simple, but hopefully you know basic regex:
This will replace the string SEARCH with REPLACE in every file (that is, * ). The /g means global, so if you had a SEARCH_SEARCH.jpg , it would be renamed REPLACE_REPLACE.jpg . If you didn’t have /g , it would have only done substitution once, and thus now named REPLACE_SEARCH.jpg . If you want case-insensitive, add /i (that would be, /gi or /ig at the end).
With regular expressions, you can do lots more.
Note that this rename is the prename (aka Perl rename ) command, which supports complete Perl regular expressions. There is another rename which uses patterns, and is not as powerful. prename used to be installed by default on Ubuntu (along with Perl), but now you may have to do:
Prefix
Also you can remove unwanted strings. Let’s say you had 20 MP3 files named like CD RIP 01 Song.mp3 and you wanted to remove the «CD RIP» part, and you wanted to remove that from all of them with one command.
Notice the extra space in ‘^CD RIP ‘ , without the space all files would have a space as the first character of the file. Also note, this will work without the ^ character, but would match CD RIP in any part of the filename. The ^ guarantees it only removes the characters if they are the beginning of the file.
Suffix
will change Something.pdf into Something.doc . (The reason for the backslash is, . is a wildcard character in regexp so .pdf matches qPDF whereas \.pdf only matches the exact string .pdf . Also very important to note, if you are not familiar with BASH, you must put backslashes in SINGLE quotes! You may not omit quotes or use double quotes, or bash will try to translate them. To bash \. and «\.» equals . . (But double-quotes and backslashes are used, for example «\n» for a newline, but since «\.» isn’t a valid back escape sequence, it translates into . )
Actually, you can even enclose the parts of the string in quotes instead of the whole: ‘s/Search/Replace/g’ is the same as s/’Search’/’Replace’/g and s/Search/Replace/g to BASH. You just have to be careful about special characters (and spaces).
I suggest using the -n option when you are not positive you have the correct regular expressions. It shows what would be renamed, then exits without doing it. For example:
This will list all changes it would have made, had you not put the -n flag there. If it looks good, press Up to go back, then erase the -n and press Enter (or replace it with -v to output all changes it makes).
Note: Ubuntu versions above 17.04 don’t ship with rename by default, however it’s still available in the repositories. Use sudo apt install rename to install it