regexperl

Swap filenames backwards


The following one-line script is to rename files from e.g. Foo_Bar_Baz.txt to Baz_Bar_Foo.txt:

(rename is the rename(1) utility from File::Rename.)

rename -n 's/(\w+)_(\w+)_(\w+)/join "_", reverse @{^CAPTURE}/xe' ./*.txt

It works, but currently the number of underscore-separated groups is hard-coded. That is, the script works fine for e.g. Foo_Bar_Baz, but it doesn't properly handle Foo_Bar or Aaa_Bbb_Ccc_Ddd.

How is it possible to adjust it in such a way that it will handle arbitrary number of underscore-separated groups?


Solution

  • Use split:

    rename -n 's{(.*)(?=\.txt$)}{ join "_", reverse split /_/, $1 }e' *.txt