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.

nalzok
  • 369
  • 1
  • 6
  • 23
  • I believe you were downvoted because you have not shown any evidence of an attempt. Have you tried anything yet? – jesse_b Feb 05 '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 05 '18 at 12:30
  • I didn't downvote the question btw but yes that is an excellent idea. – jesse_b Feb 05 '18 at 12:36
  • 1
    Macs have `perl`, so the easiest way to do this is to install the [File::Rename](https://metacpan.org/release/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 05 '18 at 14:41
  • 2
    See also https://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 05 '18 at 14:55
  • @Kusalananda I’m done! – nalzok Feb 07 '18 at 11:03

4 Answers4

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)

jesse_b
  • 35,934
  • 12
  • 91
  • 140
  • 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 05 '18 at 14:47
  • @WillCrawford Please write up an answer, that is much better than my solution. – jesse_b Feb 05 '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 05 '18 at 16:07
2

You could also use find:

 find . -name "essay.*" -exec sh -c 'mv $1 new_name.${1##*.}' rename {} \;
Rastapopoulos
  • 1,569
  • 1
  • 10
  • 21
1

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

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

courtesy of this answer.

nalzok
  • 369
  • 1
  • 6
  • 23
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
Praveen Kumar BS
  • 5,139
  • 2
  • 9
  • 14