5

Problem

I have thousands folders, which names are structured like:
firstName_lastName_date
for which I want to swap the two first parts using the underscore _ as a separator in order to end up with:
lastName_firstName_date

Warning

lastName may be be preceded by a nobiliary particle, separated with an extra _ in the input folders.
For example:
firstName_de_lastName_date
firstName_von_lastName_date

For which the wanted output should be:
de_lastName_firstName_date
von_lastName_firstName_date

Information

  • date is always the last element.
  • First names are single words.
  • Last names are single words or composed words (2) with a particle.

Tools

I want to do that using rename in bash, preferably, or shell Parameter expansion.

References

https://www.gnu.org/software/sed/manual/html_node/Regular-Expressions.html

  • Can a last name have multiple parts in addition to the particle? Or a first name? Can you have something like Jose_Maria_de_los_lobos_y_garcia_date? Or can we be sure there will always be either 3 or 2 _ and whatever is between the 1st and last _ will be the last name? – terdon Jan 19 at 13:29
9

You can do it using the Perl-based rename I think, using a mix of non-greedy and greedy matches ex.

$ rename -n 's/^(.*?)_(.*)_(.*?)$/$2_$1_$3/' *
rename(firstName_de_lastName_date, de_lastName_firstName_date)
rename(firstName_lastName_date, lastName_firstName_date)
rename(firstName_von_lastName_date, von_lastName_firstName_date)

The non-greedy modifier on the last (date) group isn't really necessary - but I like the symmetry.

Alternatively, with the shell alone

$ for f in *; do 
    m="${f#*_}"; m="${m%_*}"; echo mv -- "$f" "${m}_${f%%_*}_${f##*_}";
  done
mv -- firstName_de_lastName_date de_lastName_firstName_date
mv -- firstName_lastName_date lastName_firstName_date
mv -- firstName_von_lastName_date von_lastName_firstName_date

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.