I have a bunch of directories with author's names as "first [mi] last" (middle initial/name could be multiples), and I'd like to change them to "last, first mi". So I'd like a way to parse the name into multiple tokens, then rearrange the tokens.

In awk, it would be something like:

ls | awk print '$NF", "  $1,$2 ...'   
  • 3
    Unless you know all the last names are one word only it's most likely an impossible task... How could a script determine that Johannes Diderik van der Waals' last name is van der Waals and not Waals ? – don_crissti Jul 8 '16 at 0:03
  • Notwithstanding the constraints noted by @don_crissti, my go-to for this kind of thing would be the perl-based rename/prename command - does your system have it? – steeldriver Jul 8 '16 at 0:34
  • @don_crissti: Thanks, I hadn't considered that, and I think you're right. But for my case, it won't really matter, as I can handle a few (if any) exceptions by hand. I just want to avoid renaming all of them by hand. So, even if I only automate 75%, it's a big help. – Marty Fried Jul 8 '16 at 14:23

This should work and be shell-agnostic, run it as a script with a single parameter which is your base directory.

  1. It uses find to get the names of directories one per line, assuming they are located immediately below the supplied base directory and excluding any that have already been converted.

  2. It uses awk to strip the base directory from the list, leaving on each line just the name of the immediate directory which is the one you want to change. (awk here uses / as a field delimiter and prints the last field on each line.)

  3. It uses awk a second time to print out a mv command to rename each of these directories in the way you requested. (awk here uses the default whitespace as a field delimiter.)

  4. Save the output to a file and then execute it when you are satisfied it looks right.


find "$1" -mindepth 1 -maxdepth 1 -type d -not -name "*,*"|\
awk -F/ '{print $NF}'|\
awk -v DIR="$1" '{printf "mv \"" DIR "/" $0 "\" \"" DIR "/" $NF", "; for (i=1; i<NF; i++) {printf $i" "}; printf "\"\n"}'
  • Thanks, that seems to work well. I don't know awk very well, so I'll play around with it to make sure I understand the details so I'll learn a bit, but the listing looks great. – Marty Fried Jul 8 '16 at 14:27

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.