0

I'm trying to sort my files by pattern into filename by creating Linux Script (Bash).

My files are mostly .JPG, some .AV and .MP4. I can't use meta tags, because this files have broken tags (restored from RAID crash).

Majority of my file are with tag like this Seaxxx_A01_xxx.jpg or Beach_xxx_A01A02_xxx.jpg or Mountain_xxx_A04A12_xxx.jpg (this is my reference for who took pics and device ie : camera, reflex, etc ...).

My need is to put file to the correct folder and subfolder, based on file name.

I've think achieve this task like this :

use find, look for pattern [A-Z][0-2][0-6] or [A-Z][0-2][0-6][A-Z][0-2][0-6], when this pattern is found, look for the first filename part, (ie Sea, beach, mountain, family, etc..., always placed as the first words, normaly I don't have anything other before) and use the first part to look for a folder with a similar name and put it on (if my file contain : Sea_Royan_xxx_A04A10_xxx.jpg and I have only a folder named "Sea" it must be placed into).

On each folder, subfolders are presents, like A01, A02, A03, A04 or Dio, Sandy, Mael, etc ... and I want the current found file (ie the same than the one used to placed into parent folder, Sea, mountain, etc...) be checked for the second pattern listed above be used to put on correct subfolder.

In fact and more siply I need : Look for files, when found, check filename and use two pattern to move it on the right folder and subfolders.

Let me know how I can do it (I know how look for files, based on pattern, but not how to read the current found filename and on this filename check for two pattern to be used as correct PATH), if you have a more easiest way or better way to do this feel free to let me know!

  • It's difficult to help you because you don't clearly explain how to decide where to put each file. What do you mean by “similar name”? Where would you put Sea_Royan_xxx_A04A10_xxx if there's no directory named Sea? – Gilles Sep 28 '16 at 22:20
0

Here is one possible approach, that probably is not the most beautiful nor the most original though. The idea is to use regular expressions in awk to extract the relevant bits from file names. Then we move on to build the shell move (mv) command in awk. Finally we use the system command available in awk to execute the command and move the files to the proper subfolders.

Try this first to get a verbose description:

find . -mindepth 1 -maxdepth 1 -type f | awk '{ filename=$0; match(filename, "^([^_]+).*_(A.*)_", capture); folder=capture[1]; subfolder=capture[2];  cmd=("mv " "" filename " "  folder "/" subfolder); print "Command to be run: ", cmd }'

Result:

Command to be run:  mv ./Seaxxx_A01_xxx.jpg ./Seaxxx/A01
Command to be run:  mv ./Mountain_xxx_A04A12_xxx.jpg ./Mountain/A04A12
Command to be run:  mv ./Beach_xxx_A01A02_xxx.jpg ./Beach/A01A02

To actually execute the command you add system(cmd) at the end of the statement:

find . -mindepth 1 -maxdepth 1 -type f | awk '{ filename=$0; match(filename, "^([^_]+).*_(A.*)_", capture); folder=capture[1]; subfolder=capture[2];  cmd=("mv " "" filename " "  folder "/" subfolder); print "Command to be run: ", cmd; system(cmd) }'

The one thing you'll probably want is to adjust the regex to your needs. I am assuming you are familiar with regex, here we are capturing two portions of the file names. The capture groups are enclosed within parentheses.

Starting from the beginning of the file name we grab everything that isn't underscore, until we find one underscore. Then we keep looking until we find the pattern A#####, where # represent letters/digits (the second capture group). We capture until we hit the next underscore.

  • Hello Anonymous, – Dio Oct 17 '16 at 6:16
  • Thank you for your help, I'm sorry I haven't go any mail about your reply, so I'm just responding now ... Ok, I'll try it and go back ! Thanks !! – Dio Oct 17 '16 at 6:18

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.