user2123280
user2123280

Reputation: 21

bach linux file rename - how to rename multiple files in linux console

I would like to rename cca 1000 files that are named like: 66-123123.jpg -> abc-123123-66.jpg. So in general file format is: xx-yyyyyy.jpg -> abc-yyyyyy-xx.jpg, where xx and yyyyyy are numbers, abc is string. Can someone help me with bash or py script?

Upvotes: -3

Views: 501

Answers (5)

You can use python with standard libraries:

from pathlib import Path
from os import walk
from re import match

Path class will handle loginc about file parent directories, extensions, file names and etc. walk may be used to traversal path tree. And match will take care about searching patterns in names.

suppose we have two dirs with files:

$ tree
.
├── dir_1
│   ├── 66-123123.jpg
│   └── 67-123124.jpg
└── dir_2
    ├── 68-123125.jpg
    └── 69-123126.jpg

The following two lines of code do the trick:

f = lambda p: (res:=match("(\d+)-(\d+)", p.stem)) and p.parent/("abc-" + "-".join(res.groups()[::-1]) + p.suffix)
list(map( lambda p: print(p1:=f(p)) or (p1 and p.rename(p1)),  sum( ( [ Path(r)/x for x in ds + fs ] for r, ds, fs in walk(".", topdown=False)), [] )) )

so now we have the following:

$ tree
.
├── dir_1
│   ├── abc-123123-66.jpg
│   └── abc-123124-67.jpg
└── dir_2
    ├── abc-123125-68.jpg
    └── abc-123126-69.jpg

Using g instead of f will do the opposite

g = lambda p: (res:=match("abc-(\d+)-(\d+)", p.stem)) and p.parent/("-".join(res.groups()[::-1]) + p.suffix)

Upvotes: 0

Gilles Quénot
Gilles Quénot

Reputation: 184955

Try doing this :

rename 's/(\d{2})-(\d{6})\.jpg/abc-$2-$1.jpg/' *.jpg

warning There are other tools with the same name which may or may not be able to do this, so be careful.

If you run the following command (linux)

$ file $(readlink -f $(type -p rename))

and you have a result like

.../rename: Perl script, ASCII text executable

then this seems to be the right tool =)

If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :

$ sudo update-alternatives --set rename /path/to/rename

(replace /path/to/rename to the path of your perl's rename command.


If you don't have this command, search your package manager to install it or do it manually.


Last but not least, this tool was originally written by Larry Wall, the Perl's dad.

Upvotes: 1

petrus4
petrus4

Reputation: 614

Being able to do things like this easily, is why I name my files the way I do. Using a + sign lets me cut them all up into variables, and then I can just re-arrange them with echo.

#!/usr/bin/env bash

set -x

find *.jpg -type f | while read files
do
newname=$(echo "${files}" | sed s'@-@+@'g | sed s'@\.jpg@+.jpg@'g)
field1=$(echo "${newname}" | cut -d'+' -f1)
field2=$(echo "${newname}" | cut -d'+' -f2)
field3=$(echo "${newname}" | cut -d'+' -f3)

finalname=$(echo "abc-${field2}-${field1}.${field3}")
mv "${files}" "${finalname}"
done

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246744

for file in ??-??????.jpg ; do
    [[ $file =~ (..)-(......)\.jpg ]]
    mv "$file" "abc-${BASH_REMATCH[2]}-${BASH_REMATCH[1]}.jpg" ; 
done

This requires bash 4 for the regex support. For POSIXy shells, this will do

for f in ??-??????.jpg ; do
    g=${f%.jpg}  # remove the extension
    a=${g%-*}    # remove the trailing "-yyyyyy"
    b=${g#*-}    # remove the leading "xx-"
    mv "$f" "abc-$b-$a.jpg" ; 
done

Upvotes: 1

anumi
anumi

Reputation: 3947

You could use the rename command, which renames multiple files using regular expressions. In this case you would like to write

rename 's/(\d\d)-(\d\d\d\d\d\d)/abc-$2-$1/' *

where \dmeans a digit, and $1 and $2 refer to the values matched by the first and second parenthesis.

Upvotes: 0

Related Questions