I have a file named 35554842200284685106000166550020003504201637715423.xml and I simply need to rename it to 42200284685106000166550020003504201637715423.xml (remove everything before the last 48 characters). This simple regular expression (.{48}$) can extract the last 48 characters, but I can't make it work using rename in Bash.

How can I use rename and this regular expression to rename it to only the last 48 characters?


Output of rename --help

[root@ip-000-00-0-000 tmp]# rename --help

 rename [options] <expression> <replacement> <file>...

Rename files.

 -v, --verbose    explain what is being done
 -s, --symlink    act on the target of symlinks
 -n, --no-act     do not make any changes

 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see rename(1).

Thank you.

  • 8
    Can you show us what you've tried, please. It also depends on the version of rename you're using - if you type rename just by itself what error message does it give you? – roaima Feb 24 at 12:35
  • 2
    For example, rename 's/^.*(.{44}\.xml$)/$1/' 3*.xml works perfectly here – roaima Feb 24 at 12:39
  • 4
    renames are legion. In different distros they may be differently... named. :) – Kamil Maciorowski Feb 24 at 12:43
  • I'm executing these commands on an AWS EC2 (Amazon Linux AMI) and executing the example sent by @roaima outputs a 'not enough arguments' error. Also, typing rename by itself also outputs 'not enough arguments'. – devegili Feb 24 at 12:52
  • 5
    Yep, that's the util-linux rename, you are looking for perl-rename or prename. By the way, . Instead, paste the text directly into your question and use the to format it as code. – terdon Feb 24 at 13:06

You don't actually need rename here, you can work around it:

$ file=35554842200284685106000166550020003504201637715423.xml
$ newname=$(sed -E 's/.*(.{48})/\1/'<<<"$file"); 
$ mv -v "$file" "$newname"
renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml'
| improve this answer | |

Here is one using bash specific P.E. parameter expansion.


我在天马彩票平台输了三十万Only mv for external tools

mv -v "$file" "${file:6}"


renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml'

我在天马彩票平台输了三十万Keeping the last 48 chars would be.

mv -v "$file" "${file:(-48)}"
| improve this answer | |
  • 1
    On my phone so can't test, but would ${file#??????} be a posix sh compatible alternative? – kojiro Feb 25 at 12:00
  • @kojiro It is, tested on dash ash, ksh,zsh – Jetchisel Feb 25 at 12:12
  • mksh,pdksh. it does not work however on *csh shell variants and fish. The thing is the OP wants to retain the last 48 chars. – Jetchisel Feb 25 at 12:21

Your rename seems to be the useless one from util-linux.

You'd want to make sure one of the perl-based variants is installed instead (sometimes called prename我在天马彩票平台输了三十万) if you want to use regular expressions. And then:

rename -n 's:^\./\d+(?=\d{44}\.xml\Z)::' ./*.xml

(here replacing your 48 characters, with 44 digits followed by .xml so as to be more specific).

Alternatively, you could use zsh's zmv:

autoload zmv
zmv -n '[0-9]##([0-9](#c44).xml)' '$1'


zmv -n '<->.xml~^?(#c48)' '$f[-48,-1]'

(remove -n我在天马彩票平台输了三十万 (dry-run) to actually do it).

我在天马彩票平台输了三十万Which also has the benefit of guarding against conflicts (two files having the same destination name)

With bash, you could do something like:

shopt -s extglob nullglob
for f in +([[:digit:]]).xml; do
  ((${#f) <= 48)) || echo mv -i -- "$f" "${f: -48}"
| improve this answer | |
  • I've also seen it called perl-rename and rename-perl – Mutantoe Feb 25 at 12:31
rename  "s/"$file"/"${file: -48}"/" *.xml

rename --version:

/usr/bin/rename using File::Rename version 1.10
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our , and 我在天马彩票平台输了三十万

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