119

Rename all the files within a folder with prefix "Unix_"

Suppose a folder has two files

a.txt
b.pdf

then they both should be renamed from a single command to

Unix_a.txt
Unix_b.pdf
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
vasanthi
  • 1,199
  • 2
  • 8
  • 3

9 Answers9

142

If your filenames contain no whitepace and you don't have any subdirectories, you can use a simple for loop:

$ for FILENAME in *; do mv $FILENAME Unix_$FILENAME; done 

Otherwise use the convenient rename command (which is a perl script) - although it might not be available out of the box on every Unix (e.g. OS X doesn't come with rename).

A short overview at debian-administration.org:

If your filenames contain whitespace it's easier to use find, on Linux the following should work:

$ find . -type f -name '*' -printf "echo mv '%h/%f' '%h/Unix_%f\n'" | sh

On BSD systems, there is no -printf option, unfortunately. But GNU findutils should be installable (on e.g. Mac OS X with brew install findutils).

$ gfind . -type f -name '*' -printf "mv \"%h/%f\" \"%h/Unix_%f\"\n" | sh
miku
  • 181,842
  • 47
  • 306
  • 310
  • @Matteo: Thanks the hint: updated my answer with a warning plus two examples with `find`. – miku Aug 04 '13 at 10:02
  • Also would recommend `for f in *; do [[ -f ${f} ]] && mv ...; done` to catch only files (no sub-directories, links, etc.)... – twalberg Sep 04 '13 at 20:52
  • 2
    If you quote variables as you should, then `for FILENAME in *; do mv "$FILENAME" "Unix_$FILENAME"; done` works correctly regardless of what characters are in the file names. It does move directories, sockets, symlinks and other file types too; I presume that doesn't matter. – Jonathan Leffler Jun 03 '18 at 17:48
  • Somehow this added a `.` before all my files – nullability Nov 05 '20 at 03:10
  • as of March 2022, the link to debian-administration.org doesn't work. – Dr Phil Mar 18 '22 at 01:39
  • @DrPhil, Wayback Machine to the rescue. – miku Mar 18 '22 at 09:48
91

Try the rename command in the folder with the files:

rename 's/^/Unix_/' *

The argument of rename (sed s command) indicates to replace the regex ^ with Unix_. The caret (^) is a special character that means start of the line.

Gonzalo Matheu
  • 8,984
  • 5
  • 35
  • 58
pavium
  • 14,808
  • 4
  • 33
  • 50
48

I think this is just what you'er looking for:

ls | xargs -I {} mv {} Unix_{}

Yes, it is simple yet elegant and powerful, and also one-liner. You can get more detailed intro from me on the page:Rename Files and Directories (Add Prefix)

robsiemb
  • 6,157
  • 7
  • 32
  • 46
Zheng Qsin
  • 1,463
  • 11
  • 6
  • 4
    Beware of processing the output of `ls` — it can lead to problems if there are spaces or other oddball characters in the file names. – Jonathan Leffler Jun 03 '18 at 17:50
  • is it possible to replace certain chracter(s) while renaming. For example, if the file name is 2.0.2.CR1.zip, it should become 2.0.2.GA.zip – Rishab Prasad Oct 19 '21 at 12:46
21

I recently faced this same situation and found an easier inbuilt solution. I am sharing it here so that it might help other people looking for solution.

With OS X Yosemite, Apple has integrated the batch renaming capabilities directly into Finder. Details information is available here. I have copied the steps below as well,

Rename multiple items

  1. Select the items, then Control-click one of them.

  2. In the shortcut menu, select Rename Items.

  3. In the pop-up menu below Rename Folder Items, choose to replace text in the names, add text to the names, or change the name format.

    • Replace text: Enter the text you want to remove in the Find field, then enter the text you want to add in the “Replace with” field.

    • Add text: Enter the text to you want to add in the field, then choose to add the text before or after the current name.

    • Format: Choose a name format for the files, then choose to put the index, counter, or date before or after the name. Enter a name in the Custom Format field, then enter the number you want to start with.

  4. Click Rename.

If you have a common pattern in your files than you can use Replace text otherwise Add text would also do the job.

Tejas C
  • 383
  • 2
  • 7
7

You can just use -i instead of -I {}

ls | xargs -i mv {} unix_{}

This also works perfectly.

  • ls - lists all the files in the directory
  • xargs - accepts all files line by line due to the -i option
  • {} is the placeholder for all files, necessary if xargs gets more than two arguments as input

Using awk:

ls -lrt | grep '^-' | awk '{print "mv "$9" unix_"$9""}' | sh
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
NirajW
  • 177
  • 1
  • 4
2

Also works for items with spaces and ignores directories

for f in *; do [[ -f "$f" ]] && mv "$f" "unix_$f"; done
user645527
  • 93
  • 6
1

With rnm (you will need to install it):

rnm -ns 'Unix_/fn/' *

Or

rnm -rs '/^/Unix_/' *

P.S : I am the author of this tool.

Jahid
  • 21,542
  • 10
  • 90
  • 108
  • 2
    You should go through all your answers about your utility, and add the disclaimer that you are its author. – Mogsdad May 07 '16 at 14:32
  • @Mogsdad : I don't think its that of a necessary info. If someone wants to find the author, it's pretty easy. – Jahid May 09 '16 at 13:03
  • Thank you for this tool. For some reason, `rename` doesn't work for me, but `rnm` does. – Aloso Mar 13 '19 at 01:05
1

Situation:

We have certificate.key certificate.crt inside /user/ssl/

We want to rename anything that starts with certificate to certificate_OLD

We are now located inside /user

First, you do a dry run with -n:

rename -n "s/certificate/certificate_old/" ./ssl/*

Which returns:

rename(./ssl/certificate.crt, ./ssl/certificate_OLD.crt) rename(./ssl/certificate.key, ./ssl/certificate_OLD.key)

Your files will be unchanged this is just a test run.

Solution:

When your happy with the result of the test run it for real:

rename "s/certificate/certificate_OLD/" ./ssl/*

What it means:

`rename "s/ SOMETHING / SOMETING_ELSE " PATH/FILES

Tip:

If you are already on the path run it like this:

rename "s/certificate/certificate_OLD/" *

Or if you want to do this in any sub-directory starting with ss do:

rename -n "s/certificat/certificate_old/" ./ss*/*

You can also do:

rename -n "s/certi*/certificate_old/" ./ss*/*

Which renames anything starting with certi in any sub-directory starting with ss.

The sky is the limit.

Play around with regex and ALWAYS test this BEFORE with -n.

WATCH OUT THIS WILL EVEN RENAME FOLDER NAMES THAT MATCH. Better cd into the directory and do it there. USE AT OWN RISK.

Khalil Gharbaoui
  • 6,557
  • 2
  • 19
  • 26
-1

find -execdir rename

This renames files and directories with a regular expression affecting only basenames.

So for a prefix you could do:

PATH=/usr/bin find . -depth -execdir rename 's/^/Unix_/' '{}' \;

or to affect files only:

PATH=/usr/bin find . -type f -execdir rename 's/^/Unix_/' '{}' \;

-execdir first cds into the directory before executing only on the basename.

I have explained it in more detail at: Find multiple files and rename them in Linux

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985