3

I want to achieve the following using a shell script. When a script is called with a file as a parameter, it should move the file based on a portion of its name.

For example, "Car insurance quotations_zz21.pdf" to sort into 21.Car insurance (a sub-folder of FilingCab) "2012-09-01 Home insurance quote_zz20.pdf" to sort into 20.Home insurance (a sub-folder of FilingCab)

Logically I think it should read something like this. I did programming long long time ago, so I think have the algorithm, but do not have the commands or the syntax.

Thanks a bunch for help!


FileToMove = $1
FolderNo = (The number after zz and before a .)
ParentFolder = (~/FilingCab)
FolderList = (List of all folders in ParentFolder) 
TargetFolder = (Folder among FolderList that begins with FolderNo) - use grep?

if TargetFolder <> not empty
         cd ParentFolder
         mv FileToMove to TargetFolder
end with success
else
         do nothing
endif

end script
Renan
  • 17,136
jim70
  • 173

1 Answers1

2

Try something like this:

#! /bin/bash

# Config variable(s)
ParentFolder="~/FilingCab"

# arg processing (minimalist :)
FileToMove="$1"

# use sed to extract folder number from filename.
FolderNo=$(echo "$FileToMove" | sed -r -e 's/.*zz([0-9]+)\.pdf/\1/')

# use find to search for subdirectories of parent folder that begin
# with the folder no followed by a '.'
TargetFolder=$(find "$ParentFolder" -maxdepth 1 -type -a -d -name "${FolderNo}.*")

NumFolders=$(echo "$TargetFolder" | wc -l)

if [ "$NumFolders" -eq 1 ] ; then 
 mv "$ParentFolder/$FileToMove" "$TargetFolder/" 
else
  echo "Error: $NumFolders beginning with "$FolderNo." found" >&2
  exit 1
fi

Note the double-quotes around all the variable names. It's always the safe/correct thing to do but in your case it's essential because the filenames and directory names you gave as examples have space characters in them.

The -maxdepth 1 in the find command only searches for direct subdirectories of $ParentFolder (i.e. ignores subdirs of subdirs). If that's not what you meant, just remove that part. This find searches for any subdirectories of $ParentFolder that begin with $FolderNo.

I'm not entirely sure what you mean by "if TargetFolder is not equal to not empty", i'm assuming you meant "is the string $TargetFolder non-empty". Ordinarily, I'd check if $TargetFolder existed and was a directory but since we're getting the directory name from a find -type d, it can only be empty or a directory. or maybe more if there's more than one beginning with "$FolderNo."

I think it's better to check if we get one and exactly one result from the find. Any other value is an error, and we can't move the file. 0 means no matching folders found. 2 or more means more than one folder beginning with "$FolderNo." was found.

The warning msg to stderr is optional. so is the exit 1, but recommended. It allows you to call this script from another script and check whether it was successful or not.

cas
  • 78,579
  • BTW, you could easily make the script process multiple files at once by changing FileToMove="$1" to for FileToMove in "$@" ; do, and adding done to terminate the for-loop as the last line of the file. – cas Sep 01 '12 at 15:17
  • Wow. This looks like will work. I will try it out and report back! Thank you for the help! Btw, I am doing this on a Mac, and had the option of trying to figure out using AppleScript, but since Unix commands are so much more capable (I feel). And your script shows how compact this can be! I will try this out and also read sed manual again. – jim70 Sep 01 '12 at 16:07
  • Craig, the -r option in sed does not seem to work on a Mac. I looked up the manual for sed and it appears that -r option is "less portable". I will look up the sed manual for Mac. Looked it up here and no -r option. https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/sed.1.html Any ideas as to what to do? MEanwhile, I will study up the Mac sed and see what I can do with it. – jim70 Sep 01 '12 at 17:23
  • Upon more research it appears -E might be the flag on Mac to replace -r. So -E worked. Now to debug find etc. Will do and update. – jim70 Sep 01 '12 at 17:37
  • The script now works. Thank you for the help and for the tips as to why you included double-quotes. And your thinking about how find should return only one answer is spot on! – jim70 Sep 01 '12 at 20:15
  • -r in GNU sed and apparently -E in Mac's sed both tell sed to use extended regular expressions. The main difference between extended and basic regexps is that the some of the syntactically significant characters in regexp (){}+|?* are treated as literal strings in basic and have to be backslash-escaped to have their special meaning. In extended regexps, the situation is reversed and they have to be escaped to be treated as literal strings. I generally prefer to use extended because with less backslashes, the regexp is IMO more readable and less cryptic. – cas Sep 02 '12 at 01:00
  • also, -r in GNU sed is an odd quirk. IMO, it should be -E to match the same option in GNU grep....but changing it now would break too many existing scripts that use -r. – cas Sep 02 '12 at 01:02
  • Got it! and thanks again! I wish Stack exchange sent me an alert that there are comments after mine on this question. I came back here as I had another question about what script language to use for something else that I need. Will ask that as a separate question. – jim70 Sep 07 '12 at 14:10