1

Say I have these files:

essay.aux                   essay.out
essay.dvi                   essay.pdf
essay.fdb_latexmk           essay.tex
essay.fls                   essay.toc
essay.log                   ......

How do I rename them to:

new_name.aux                new_name.out
new_name.dvi                new_name.pdf
new_name.fdb_latexmk        new_name.tex
new_name.fls                new_name.toc
new_name.log                ......

The problem is that they have different extensions rather than different names, so I cannot use answers from this question. Also, I'm on macOS which doesn't have a rename command.

  • I believe you were downvoted because you have not shown any evidence of an attempt. Have you tried anything yet? – Jesse_b Feb 5 '18 at 12:27
  • 1
    @Jesse_b It's dangerous for a rookie to execute anything from the command line, right? I really don't want to risk losing my files. But since you've asked, I'll make a new directory and touch some random files and do some experiments ;) – nalzok Feb 5 '18 at 12:30
  • I didn't downvote the question btw but yes that is an excellent idea. – Jesse_b Feb 5 '18 at 12:36
  • 1
    Macs have perl, so the easiest way to do this is to install the File::Rename CPAN module, then you can use the rename script which is included as an example. It's the same perl rename script mentioned in many answers to similar questions on this site. It's more work up-front, but then you have the best file-renaming tool available for all future renaming tasks. – cas Feb 5 '18 at 14:41
  • 2
    See also superuser.com/a/345527/4877 - in short, if you have brew already installed - and you should - just run brew install rename. This is not the same as the File::Rename script but was inspired by it. It seems to have many more command-line options, but is backwards compatible with the rename referenced here so frequently. – cas Feb 5 '18 at 14:55
3

Here is a solution I was able to get working:

#!/bin/bash
shopt -s nullglob

my_files='/root/temp/files'
old_name='essay'
new_name='new_name'

for file in "${my_files}/${old_name}"*; do
    my_extension="${file##*.}"
    mv "$file" "${my_files}/${new_name}.${my_extension}"
done
  • shopt -s nullglob

This will prevent an error if the directory it's parsing is empty

  • for file in "${my_files}/${old_name}"*; do

We are going to loop over every file in /root/temp/files/ so long as it begins with essay

  • my_extension="${file##*.}"

This will greedily trim anything up to the last . found in the filename (hopefully leaving you with only the extension)

  • mv "$file" "${my_files}/${new_name}.${my_extension}"

This moves the old file to the new filename while reserving the extension. (rename)

  • 1
    If you cd to that directory, you can change the names in one step (in bash at least) with ${file/#old/new} i.e. mv "$file" "${file/#old/new}" – Will Crawford Feb 5 '18 at 14:47
  • @WillCrawford Please write up an answer, that is much better than my solution. – Jesse_b Feb 5 '18 at 16:04
  • It's just a change to the line in your loop, it still needs the for file in ... ; do ... ; done around it. – Will Crawford Feb 5 '18 at 16:07
2

You could also use find:

 find . -name "essay.*" -exec sh -c 'mv $1 new_name.${1##*.}' rename {} \;
1

If you're using zsh, you could do this:

autoload zmv
zmv -w 'essay.*' 'new_name.$1'

courtesy of this answer.

1

I Have used below command to get the output

First i have used for loop in for loop i have mentioned all the file extensions then in loop i have used awk command to rename the file as per requirements.

Tested and worked fine

command

for i in aux out dvi pdf fdb_latexmk tex fls toc; do  find . -type f -iname "*.$i"| awk -F "./" '{print $2}' | awk -F "." '{print "mv" " " $1"."$2 " " "new_name."$2}'| sh; done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.