I have a directory filled with thousands of files in the format LastnameFirstnameYYYYMMDD.pdf. The last and first name will always been in title case.

I'd like to extract the last name so I can move these files to a directory structure of {first letter of last name}/lastname/full filename. Example: DoeJohn20190327 would be moved to D/Doe/DoeJohn20190327

  • 3
    Check out 'sed' and 'awk' – Tintin Mar 29 '19 at 4:15
  • 1
    I'm not sure if the final destination of the file DoeJohn20190327.pdf is like this: D/Doe/DoeJohn20190327/DoeJohn20190327.pdf or D/Doe/DoeJohn20190327/DoeJohn20190327.pdf ? – Philippe Delteil Mar 29 '19 at 15:37

Here you have a solution. I tested it an it creates the folders as you explained.

for filename in *.pdf
  echo "Processing file $filename "
  mkdir -p $first_letter #if already exists won't print error
  last_name=$(echo $filename | sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g'  |awk '{print $1}')
  mkdir -p $first_letter/$last_name
  mv $filename $first_letter/$last_name

If the lastname is always the shortest trailing string staring with an upper case letter (there are no compound lastnames for example) you could use a shell parameter expansion of the form ${parameter%pattern} in place of a regex solution.


for f in [[:upper:]]*[[:upper:]]*; do 
  echo mkdir -p "$d"
  echo mv "$f" "$d"
mkdir -p D/Doe/
mv DoeJohn20190327 D/Doe/

Remove the echos when you are satisfied that it is doing the right thing.

See for example Parameter Expansion

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.