Renaming a file in Bash using regular expressions
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'
Here is one using bash specific P.E. parameter expansion.
file=35554842200284685106000166550020003504201637715423.xml
Only mv for external tools
mv -v "$file" "${file:6}"
Output
renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml'
Keeping the last 48 chars would be.
mv -v "$file" "${file:(-48)}"
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'
Or
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}"
done