I'm creating a bash script to rename my files. The files are in the same folder and all look something like this

1xxx_(bunch of characters)=(bunch of characters)=1234567890

Now what i want is to leave just the last 1234567890. Basically deleting every character from the front to the second occurrence of =


You can use the shell's parameter expansion feature: in particular

       Remove matching prefix pattern.  The word is expanded to produce
       a pattern just as in pathname expansion.  If the pattern matches
       the  beginning of the value of parameter, then the result of the
       expansion is the expanded value of parameter with  the  shortest
       matching  pattern  (the ``#'' case) or the longest matching pat‐
       tern (the ``##'' case) deleted.

So something like

for file in *; do echo mv -- "$file" "${file##*=}"; done

(remove the echo if it appears to do the right thing).

One issue you may face is that filenames may become non-unique once the prefixes are removed. You can either choose to skip renaming these cases using the -n or --no-clobber option to mv:

for file in *; do mv --no-clobber -- "$file" "${file##*=}"; done

or use the -b or --backup option to create distinct backups: most straightforwardly

for file in *; do mv --backup=numbered -- "$file" "${file##*=}"; done

which will add distinguishing suffixes .~1~, .~2~ and so on.

  • As you stated it works great,but now i figured out i have couple of hundreds files with the same characters,like 1393514394 so the second occurrence is not renamed,any way to add "a" like 1393514394a ,1393514394 b etc for the duplicate files ? – OneStyle07 Dec 29 '15 at 22:43
  • @OneStyle07 look at the -b or --backup options of the mv command: for example, adding --backup=numbered will add default suffixes like .~1~, .~2~ – steeldriver Dec 29 '15 at 22:51
  • What that -- is doing in the mv command of your answer? – Kira Dec 29 '15 at 22:56
  • @Kira the -- is a (more-or-less) standard way to denote the end of command options: it just makes commands like this safe in the case that there are filenames beginning with a hyphen (in this case there wouldn't be, given the 1xxx* glob). – steeldriver Dec 29 '15 at 23:03
  • @OneStyle07 please see edits – steeldriver Dec 29 '15 at 23:23

The perl rename script (comes standard in debian/ubuntu, or available here: http://tips.webdesign10.com/files/rename.pl.txt ) will rename files based on a regular expression. with -n it will just print the named files without actually renaming them, allowing you to test before performing the action:

# Check before renaming...
$ rename -n 's/^.*=//' *
1xxx_DSAFDSAFDSFA=FDAFDSAFDSAFSDA=12341243142 renamed as 12341243142

# now rename all files
$ rename 's/^.*=//' *

It is very flexible tool, as it can easily operate on files based on wildcards (e.g. * for all files or *.txt for all text files), and it accepts any perl regular expression.

  • It is sed for file name: sed does file content, rename does their names. – ctrl-alt-delor Dec 30 '15 at 21:32

awk can save the day here too. I'm using cp there, change it to mv if you like:

ls | awk -F"=" '{system("cp -i "$0" "$3)}'

I would use -i as a cp parameter too, just to be safe.

  • I get sh: 1402190714: command not found usage: mv [-f | -i | -n] [-v] source target mv [-f | -i | -n] [-v] source ... directory usage: mv [-f | -i | -n] [-v] source target mv [-f | -i | -n] [-v] source ... directory – OneStyle07 Dec 29 '15 at 22:29
  • Did you try to add parameters to mv? Make use to put it inside the quotes and to put spaces around it. I've edited the answer to show that. – Kira Dec 29 '15 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.