Rename files with numbers linux

Renaming files in a folder to sequential numbers

I want to rename the files in a directory to sequential numbers. Based on creation date of the files. For Example sadf.jpg to 0001.jpg , wrjr3.jpg to 0002.jpg and so on, the number of leading zeroes depending on the total amount of files (no need for extra zeroes if not needed).

@maXp. This will likely not handle special chars correctly. Also never use ls without —color=never .

28 Answers 28

ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done 

You can change .ext with .png , .jpg , etc.

add printf like this: ls | cat -n | while read n f; do mv «$f» `printf «%04d.extension» $n`; done to have zero padded numbers

Warning: You might want to add -n to the mv command to prevent accidentally overwriting files. Discovered this the hard way!

Putting together some great ideas from comments on this answer and others: ls -1prt | grep -v «/$» | cat -n | while read n f; do mv -n «$» «$(printf «%04d» $n).$»; done Results: (1) sorted in order of modification, later files with later indexes; (2) ignores directories — and not recursive; (3) pads indexes; (4) maintains original extension.

Try to use a loop, let , and printf for the padding:

a=1 for i in *.jpg; do new=$(printf "%04d.jpg" "$a") #04 pad to length of 4 mv -i -- "$i" "$new" let a=a+1 done 

using the -i flag prevents automatically overwriting existing files, and using — prevents mv from interpreting filenames with dashes as options.

Could just be Cygwin (although it’s terminal behaviour is largely identical to normal Unix shells) but it seems to have a problem when there are spaces in the filename.

It would probably also be desirable to use mv — «$i» «$new» to correctly handle source filenames that start with dashes; as it is, mv will try to parse such filenames as collections of flags.

I have lost about 800 files at a glimpse. I think -i should be included in the answer and note should be rewritten accordingly. that’ll be more safe. 🙁

I like gauteh’s solution for its simplicity, but it has an important drawback. When running on thousands of files, you can get «argument list too long» message (more on this), and second, the script can get really slow. In my case, running it on roughly 36.000 files, script moved approx. one item per second! I’m not really sure why this happens, but the rule I got from colleagues was » find is your friend».

find -name '*.jpg' | # find jpegs gawk 'BEGIN< a=1 >< printf "mv %s %04d.jpg\n", $0, a++ >' | # build mv command bash # run that command 

To count items and build command, gawk was used. Note the main difference, though. By default find searches for files in current directory and its subdirectories, so be sure to limit the search on current directory only, if necessary (use man find to see how).

Читайте также:  Rsync linux server to server

breaks down in case filename has spaces. Use quotes around the source filename. printf «mv \»%s\» %04d.jpg\n», $0, a++

The for loop is not taking 1 second per file, strictly speaking. It is taking a long time to fetch the 36,000 file names from the file system, then loops over them reasonably quickly. Many file systems have issues with large directories, regardless of which precise commands you run; but typically, find is going to be faster than a shell wildcard because it has to fetch and sort the list of matching files.

@Pero Your usage of mv is dangerous. Besides @CharlesDuffy’s objections, what happens if there (before running your script) already is a file with name 0001.jpg , for example? It will be silently overwritten by the first file treated. Secondly, if a file happens to start with a dash, mv treats the rest of the file name as flags. Both problems have been mentioned in the comments to gauteh’s answer, as well as their solution: Use mv -i — instead of mv . Apart from that, I agree that using find is better than using a shell glob, for the reason you have pointed out.

A very simple bash one liner that keeps the original extensions, adds leading zeros, and also works in OSX:

num=0; for i in *; do mv "$i" "$(printf '%04d' $num).$"; ((num++)); done 

@RoyShilkrot What do you mean by »will not keep the original order«? Globs in bash and other posix shells expand in sorted order according to the system’s locale. Of course, this does not sort 9.ext before 11.ext , but other tools (like ls ) won’t do so either.

No, this is likely a dangerous solution not to mention the fact that special chars and spaces in file names will not work correctly.

using Pero’s solution on OSX required some modification. I used:

find . -name '*.jpg' \ | awk 'BEGIN< a=0 >< printf "mv \"%s\" %04d.jpg\n", $0, a++ >' \ | bash 

note: the backslashes are there for line continuation

edit July 20, 2015: incorporated @klaustopher’s feedback to quote the \»%s\» argument of the mv command in order to support filenames with spaces.

Like Pero’s solution, there are security vulnerabilities here. Think about if you have a file named $(rm -rf /).jpg .

Thanks, this works. But you should quote the first argument to mv . If you have a file named i.e. some thing.jpg your script fails. This is what I used: find . -name ‘*.jpg’ | awk ‘BEGIN< a=0 >< printf "mv \"%s"\ wallpaper-%04d.jpg\n", $0, a++ >‘ | bash

i would probably use -maxdepth 1 to work only on jpgs in current directory, as it’s better to be safe than sorry.

I’m interested in knowing where one gets a rename command with -N option. My Ubuntu 14.04 doesn’t have it.

Читайте также:  Программное обеспечение операционной системы линукс

There are at least three different tools known as rename . The link posted by @Bostrot is yet another rename tool and it seems like @RomanRhrnNesterov used that one. ¶ To all the users of rename by Peder Stray and Larry Wall (package perl-rename on arch linux and package rename on debian/ubuntu): You can define $N yourself: perl-rename ‘$N=sprintf(«%04d»,++$N); s/.*/$N.jpg/’ *.jpg

To work in all situations, put a \» for files that have space in the name

find . -name '*.jpg' | gawk 'BEGIN< a=1 >< printf "mv \"%s\" %04d.jpg\n", $0, a++ >' | bash 

Does not in fact cover all situations. A filename containing literal quotes could trivially escape — and since you’re using double quotes rather than single quotes, expansions like $(rm -rf /) are still honored.

On OSX, install the rename script from Homebrew:

Then you can do it really ridiculously easily:

That’s a great script, and it only depends on Perl. brew only works on macs, but you can grab it from github (github.com/ap/rename) and use it on Linux or Windows.

this doesn’t work for me. I got Global symbol «$N» requires explicit package name (did you forget to declare «my $N»?) at (user-supplied code).

As a Mac user, I’m happy to report that the rename application linked to by @TimDanner is super portable, it was as easy as downloading the Zip archive, dropping the rename utility into a directory that my bash profile path is set to see, and it works right out of the box. I’m surprised this isn’t available on MacPorts. I find it so weird that I have a BSD manpage for Rename (2) but when run rename it would say no command exists. Go figure.

NOTE The rename commands here include -n which previews the rename. To actually perform the renaming, remove the -n

If your rename doesn’t support -N , you can do something like this:

ls -1 --color=never -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e' 

NOTE The rename commands here includes -n which previews the rename. To actually perform the renaming, remove the -n

Edit To start with a given number, you can use the (somewhat ugly-looking) code below, just replace 123 with the number you want:

ls -1 --color=never -c | xargs rename -n 's/.*/our $i; if(!$i) < $i=123; >sprintf("%04d.jpg", $i++)/e' 

This lists files in order by creation time (newest first, add -r to ls to reverse sort), then sends this list of files to rename. Rename uses perl code in the regex to format and increment counter.

However, if you’re dealing with JPEG images with EXIF information, I’d recommend exiftool

This is from the exiftool documentation, under «Renaming Examples»

Источник

rename multiple files in linux with number plus a constant

where the additional constant (here 200) can be specified.

I’ve tried something along the lines of that suggested in Renaming a set of files to 001, 002, . on Linux

i=200; temp=$(mktemp -p .); for file in solution_*.vtu do mv "$file" $temp; mv $temp $(printf "solution_%0.3d.vtu" $i) i = $((i+1)) done 

but this doesn’t work for me. Thanks for any help!

Читайте также:  Install x11 on linux

Share some code you tried at this point, and explain on what you are stuck because we will not do the whole script for you

2 Answers 2

You can try with this command:

 find . -printf 'mv %f %f\n' | grep -v '\. \.' | sed 's/u Solution_/u Solution_2/g' | while read -r i ; do $i ; done 

Thank you for your reply, but this isn’t quite what I was looking for as this just appends an extra 2. I.e. if I have Solution_200.vtu Solution_201.vtu I will get Solution_2200.vtu Solution_2201.vtu instead of Solution_400.vtu, Solution_401.vtu which is what I really need.

If you have ruby on your Linux machine :

#! /usr/bin/env ruby require 'fileutils' pattern = ARGV[0] || "*.vtu" offset = (ARGV[1] || 200).to_i Dir[pattern].each do |file| if id then new_id = id.to_i + offset new_file = file.sub(/\d+/, new_id.to_s) puts "# -> #" ## UNCOMMENT THIS LINE IF YOU WANT TO MOVE FILES: # FileUtils.mv file, new_file end end 
./rename_with_integer_offset.rb "*.vtu" 200 # solution_201.vtu -> solution_401.vtu # solution_202.vtu -> solution_402.vtu 

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Bulk rename files with numbering

How do I bulk rename multiple files named Image401.jpg, Image402.jpg. to Image 001.jpg, Image002.jpg, . ?

2 Answers 2

Under Linux, to change the first 4 in the file names to 0 :

Under Debian, Ubuntu and derivatives, rename is a different file renaming program, which is based on a Perl expression. Either call rename.ul instead, or call the Perl renaming script:

You just want to change ‘4’ to ‘0’?

for f in Image4*.jpg do # replace Image4 prefix with Image0 newname="Image0$" mv "$f" "$newname" done 

Or you want to subtract 400 from the numeric part? Or something else?

mv «$f» Image0″$» is a much faster and safer way to do this. The $( echo | sed ) approach, even if it works on filenames like Image401.jpg , is not very robust as it will mangle filenames containing odd characters or spaces, and is much slower because of the extra temporary subshell and processes created for every single file.

You must log in to answer this question.

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533

Linux is a registered trademark of Linus Torvalds. UNIX is a registered trademark of The Open Group.
This site is not affiliated with Linus Torvalds or The Open Group in any way.

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Оцените статью
Adblock
detector