-1

How do you use Perl's rename to replace the names of all files in a folder with a custom string and an index? I suspect the answer is pretty simple. Still, I haven't been able to piece it together from the manual or the other answers here on SO.

Example

In folder foo I have the files

long complicated name 1.png
random_string_of_letters.png
12312434235512351.png
etc.

The only common denominator is that they have the same extension. I want to rename them

bar1.png
bar2.png
bar3.png
etc.

I'm using Perl's rename (installed via homebrew). The closest I've come is this piece of code from another answer rename -nvs searchword replaceword *. But I am unable to adapt it to do what I wish. I'm used to read * as a wildcard, but it seems to have a different purpose here. I know that you can use regex if you remove -s from the command, and that regex is different from "normal" regex (see a comment to the same answer linked above). But not how to use it.

Edit

When I run brew info rename I get this info:

==> rename: stable 1.601 (bottled), HEAD
Perl-powered file rename script with many helpful built-ins
http://plasmasturm.org/code/rename
/opt/homebrew/Cellar/rename/1.601 (4 files, 44.9KB) *
  Poured from bottle using the formulae.brew.sh API on 2023-08-17 at 11:03:56
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/r/rename.rb
brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • Please provide info about which `rename` you have. There's more than one. To get the behaviour you want, you will need to run code for each replacement. I'll have to read the docs of the one you have to see if it can. – ikegami Aug 17 '23 at 13:22
  • I've added some info. Is that what you need? – Blue badger Aug 17 '23 at 13:41
  • yeah, [that link](http://plasmasturm.org/code/rename) is useful. Specifically, you'll find `-N` useful – ikegami Aug 17 '23 at 14:07
  • I fiddled around with -N and $N, but were not able to get them to return anything helpful – Blue badger Aug 17 '23 at 14:12
  • To be more helpful, I've tried variants like `rename -nvs -N *.png bar$N` and similar compositions. The problem is probably that I don't understand the proper way to compose my commands. Like f.ex. how I specify a wildcard that captures anything before .png. Or I'm misunderstanding how the command operates. – Blue badger Aug 17 '23 at 14:27

2 Answers2

1

You can list all files in a directory with

my @files = grep -f, <directory/*>;

Then you can iterate on this list and rename each file.

For example:

my $basename = "bar";
my $dir = "./";
my $index = 1;
for my $file (grep -f, <$dir*>) {
    my $extension = $file =~ /\.[^.]+\z/ ? $& : "";
    rename($file, "$dir$basename$index$extension");
    $index++;
}

This assumes two things: the $dir string ends with / (easily fixed) and every file name has an extension (also easily fixed).

Here's an alternative

If you don't understand Perl, then you can try this:

use strict;

my $basename = $ARGV[0] or die;
my $dir = $ARGV[1] or die;
my $output = $ARGV[2] or die;
   
$dir .= '/' unless $dir =~ m!/$!;
my $index = 1;

open F, ">$output" or die "Can't open '$output'\n";
for my $file (grep -f, <$dir*>) {
    $file =~ /\.[^.]+$/ or next;
    my $extension = $&;
    print F "mv '$file' '$dir$basename$index$extension'\n";
    $index++;
}
close F;

This will not modify anything in your system. Run like so:

perl filename.pl basename directory output.sh

Where basename is the base name you want in your files, directory is where your files are and output.sh is a script name.

This will produce a bash-style script with commands to rename the files. You can verify each rename command before running anything.

giusti
  • 3,156
  • 3
  • 29
  • 44
  • When I run your first command I get `zsh: parse error near ';'`. If I remove `;` I get `zsh: parse error near `\n'` – Blue badger Aug 17 '23 at 14:04
  • @Blue badger, That's Perl, not zsh commands. – ikegami Aug 17 '23 at 14:07
  • @Bluebadger this piece of code renames files in your system. I tried my best to make it correct, and I tested in my system, but please test it in yours first. I assumed you are a Perl programmer in need of help. Don't just copy and paste code if you don't understand. – giusti Aug 17 '23 at 14:14
  • I appreciate the effort! Unfortunately I've never used Perl. I mentioned Perl because it seems the best way to name the renamer tool because it's hard to google. – Blue badger Aug 17 '23 at 14:17
  • I really appreciate you trying to help me out with the Perl here, @giusti. But I'm realising that what I thought was a fairly simple line in `rename` is turning out to be surprisingly massive endeavour. So I'm giving up on it. You made me realise, however, that its trivial for me to rename the the files in a language I'm more familiar with, like R. `file_list <- list.files(); new_names <- c(); for (i in 1:length(file_list)) { new_names <- c(new_names, paste0("bar", i, ".png")) }; file.rename(from = file_list, to = new_names)` – Blue badger Aug 17 '23 at 14:44
1

From the docs, it looks like the following will do:

rename -Xe '$_ = "bar$N"' *.png

Add a leading -n to do a dry run.

Optionally add -v for more info.

ikegami
  • 367,544
  • 15
  • 269
  • 518