Rename all files in a folder with a prefix in a single command
Asked Answered
V

9

121

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
Violoncello answered 13/6, 2011 at 10:57 Comment(3)
check this link => cyberciti.biz/tips/…Rentschler
check here:theunixshell.blogspot.com/2013/01/…Iorgo
fast and easy: rename '' <prefix> *Adjectival
M
143

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
Media answered 13/6, 2011 at 11:10 Comment(6)
@Matteo: Thanks the hint: updated my answer with a warning plus two examples with find.Media
Also would recommend for f in *; do [[ -f ${f} ]] && mv ...; done to catch only files (no sub-directories, links, etc.)...Dilan
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.Horror
Somehow this added a . before all my filesBlintz
as of March 2022, the link to debian-administration.org doesn't work.Piker
@DrPhil, Wayback Machine to the rescue.Media
K
93

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.

Kellsie answered 13/6, 2011 at 11:3 Comment(8)
Could you explain what 's/^/.../' means?Pericynthion
@Matteo 's/^/.../' is the perl expression argument for the rename commandIsbell
this is awesome! i'd suggest to add folder/* , because * is a bit dangerous if command accidently will be repeated in another placeDorking
brew install rename @OliverPearmainDulciedulcify
Example to replace a prefix: rename 's/^start_/run_' *Brittenybrittingham
Based on your Linux distribution you may want to try to install rename, prename or perl-rename packages (they all work the same way)Umbelliferous
Requires installing rename package in linuxBachman
man rename says that you can use -v and -n to check what will be done without actually doing anything. That helps me a lot.Enthetic
D
49

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)

Dislocation answered 7/12, 2012 at 9:52 Comment(2)
Beware of processing the output of ls — it can lead to problems if there are spaces or other oddball characters in the file names.Horror
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.zipFenestella
P
22

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.

Polypetalous answered 19/1, 2016 at 18:6 Comment(2)
Excellent - saved me a lot of time!Demibastion
Great solution for Mac usersBachman
B
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
Bayless answered 17/5, 2016 at 21:12 Comment(2)
-i is deprecated, now is just -IRevolution
it's helped me on Debian 8.ThaksRhyolite
B
2

Also works for items with spaces and ignores directories

for f in *; do [[ -f "$f" ]] && mv "$f" "unix_$f"; done
Bowshot answered 29/5, 2015 at 10:31 Comment(0)
S
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.

Splotch answered 7/5, 2016 at 10:50 Comment(3)
You should go through all your answers about your utility, and add the disclaimer that you are its author.Macdonald
@Macdonald : I don't think its that of a necessary info. If someone wants to find the author, it's pretty easy.Splotch
Thank you for this tool. For some reason, rename doesn't work for me, but rnm does.Strongbox
Q
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.

Quicken answered 3/6, 2018 at 17:22 Comment(0)
C
-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

Canning answered 29/10, 2020 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.