[SOLVED] File Naming is prescribed form with next day's date as part of the name
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
File Naming is prescribed form with next day's date as part of the name
Hello Gurus,
I am working in print media house where the editorial users are to save pdf files with the name ddmmyyyyPPnnEEECCC.pdf where d = date, m = month, y = year, P = publication, n = page number, E = Edition and C = Center.
We requested the users to save the pdf files with page number as the file name, i.e. 01.pdf in a driectory tree. The directory tree is like this:
PP > CCC > EEE
Normally the date in the format, ddmmyyyy, is the next day of the current date.
Presently we are renaming the file in the requred form manually and save it another directory.
Is there a way in linux to rename the pdf file in the required naming form and move it another directory?
Your verbal description isn't very easy to understand. Could you please give us a real example of what the filenames an directory tree look like before, and how you want it to look afterwards? Are there any separators involved? Are the filenames exactly uniform in the lengths of the strings involved? If not, what kinds of variations might we see? We have to be able to account for all likely possibilities in order to be safe.
The thing should be scriptable. All that's really needed is to split the filename into it's constituent parts, update the timestamp, and reassemble it into the output filename. But how easy it is to do that depends on your answer.
And please use [code][/code] tags around your code/data, to preserve formatting and to improve readability.
Last edited by David the H.; 04-07-2011 at 06:46 PM.
Reason: minor wording change for accuracy
Thanks Mr. David the H and kaiserkar13 for the immdiate reply posted. This is of some use. To clarify my requirement:
The folder structure is as mentioned below:
-->IE (folder as well publication code)
---->BNG (folder in IE as well as center code)
-------->HSN (folder in BNG as well as edition code)
-------->MYS (folder in BNG as well as another edition code)
-------->CTY (folder in BNG as well as another edition code)
---->BGM (folder in IE as well as another center code)
-------->BGK (folder in BGM as well as edition code)
-------->GOA (folder in BGM as well as another edition code)
-------->...
-------->...
---->...
---->...
---->...
There are a lot of publications under which lot of centers within which editions are there. The publications are coded with two characters. Centers and Editions are coded with unique combination of three characters. Inside the edition folder the files will be saved by the users (e.g. .../IE/BNG/HSN/01.pdf). Now consider today's date is 08 April 2011. The file so saved should be ranamed as 09042011IE01HSNBNG.pdf (with next day's date) and moved to another folder, say .../final/.
The script may watch the sub-folders from the parent folder of publication folder for any files, rename them and move to the destination folder.
The script provided should still work, with some modifications
The code in my previous post should allow you to proceed with any directory structure you have. I'll explain some things so you can modify it yourself to fit your needs:
* sed 's+\.+/+g'
- sed = "stream editor"; used to edit pipelines on-the-fly or entire files.
- 's' means "substitute," the plus signs are separators (can be any character NOT in the search or replace field; the usual choice is '/', but that's my substitute pattern here)
- '\.' means a literal period (normally a '.' character in a pattern, known by "gurus" as a "regular expression," means ANY character, so you escape it with \. to mean the character '.')
- 'g' at the end means "global," that is, "replace all occurrences on a given line, not just the first"
- The net effect of this command is to replace every occurrence of '.' with '/', so instead of ./IE/BNG/HSN/01.pdf, you'd get //IE/BNG/HSN/01/pdf, which you can then chop up with AWK.
* awk -F '/' '{print $3 $6 $5 $4 "." $7}'
- Awk is a text processing tool (letters stand for names of authors). For a good AWK reference, try http://www.vectorsite.net/tsawk.html
- The command above just prints fields 3, 6, 5, 4, and 7, with a '.' before the 7th field and no spaces between fields.
- The '-F /' part means "use '/' as the field separator" (the default is whitespace).
- Net effect is to take a pattern like a/b/c/d/e/fgh/ijk and turn it into "cfghed.ijk"
* date +%d%m%Y
- Prints the current date, ddmmYYYY format. You can change this to another date (say, tomorrow) with flags to 'date', in this case 'date -d "tomorrow" +%d%m%Y'; see the man page ("man date").
* find . -name \*.pdf
- Prints all files under the current directory ('.') that end in .pdf. Includes all subdirectories.
* $(...) OR `...`
- include the output from the command "..." verbatim at this point in the script.
Thank you very much. Your code gave me good clue and it worked well. Appended below please find the code what I use:
Code:
cd /trans/ie
#destination=/trans/bgm/out
for pdf in `find . -name \*.pdf` ; do
filename=$(date -d "tomorrow" +%d%m%Y)$(echo $pdf | sed 's+\.+/+g' | awk -F '/' '{print $4 $3 "." $5}')
echo $filename
center=$(echo $pdf | sed 's+\.+/+g' | awk -F '/' '{print $3}')
echo $center
destination="/trans/"$center"/out"
echo "moving $pdf to $destination/$filename"
mv $pdf $destination/$filename
done
This script works well to fulfill our requirement after changing our folder structure and filename by the users (i.e. in folder trans/ie we created folder in the name of centers BGM, HUB, etc. and inside the filenames as IE01CTY (<publication><page number><edition>)). But one issue just arised after last night's test run. To tell you, our editorials work from 2 p.m. in the day till 2 a.m. in the night to bring out the newspaper for the day (nextday). The above code works well for those pdf files copied to the source folder upto 12 midnight, assigning next days date in the filename. But for those files copied after 12 midnight, as already date has changed to next day, the date in the filename goes one more day. But it should be the same date.
Is there any way to deduct 6 hours from the system time and calculate the next day's date from thereon. My requirement is like this.
Assuem todays date is 09 Apr 2011. Publication date is 10 Apr 2011 (that's next day)
Editorial works from 09 Apr 2011 02:00 pm to 10 Apr 2011 02:00 am for the publication date.
So all the pdf files that are copied to the source folders copied within the working hours should have the date 10042011 in the filename.
Sorry for the addition in the previous thread... Please help.
1) You're still not using [code][/code] tags like I asked you. Please do so from now on, and go back to edit your previous posts to add them there too. It's also a good idea to use some kind of consistent spacing and indentation style in your code, for further readability.
2) How exactly is it "not working"? What kind of output do you get? What variations have you tried and what results did you get from them? Have you tried testing each command alone to see what you get at each step?
Try running the script with !#/bin/bash -x at the top of the script to enable verbose output, or use set -x and set +x (minus for on, plus for off) to enable and disable them at certain points in your script. This will help you see what's it's really doing.
I would also put labels and enclosing brackets of some kind around your testing echos, to ensure you're getting exactly the string you want, without any extra spaces or whatnot at the end.
Code:
echo "filename: [$filename]"
3) This probably won't have any direct effect on your problems, but since $(..) is recommended over `..`, especially when it comes to nesting, you should change these lines to:
Code:
for pdf in $( find . -name \*.pdf ) ; do ...
filename=$([ $( date -d "tomorrow" +%H ) -le 2] && ... )
^
Also notice the syntax mistake I marked in the second line. You always need spaces on both sides of a test "[ .. ]" bracket.
4) I'd probably break the bolded part down into a more traditional "if..then..else" format in any case. It's easier to read and debug, and the "cmd1 && cmd2 || cmd3" structure doesn't always do what you expect it to anyway.
Code:
if (( $( date -d "tomorrow" +%H ) <= 2 )) ; then
printdate="$( date +%d%m%Y )"
else
printdate="$( date -d "tomorrow" +%d%m%Y )"
fi
namestring="$( echo "${pdf//.//}" | awk -F '/' '{print $4 $3 "." $5}' )"
filename="$printdate$namestring"
5) Notice also how in the above I replaced sed with a simple parameter substitution. The same thing can be used when setting the $center variable just after that too. I also replaced the regular [..] test with bash's ((..)) arithmetic/numeric operator, since this is a numeric comparison.
6) This line doesn't need the extra quotes in the middle. A single set around the whole string is enough:
Code:
destination="/trans/$center/out"
7) This line should also have quotes around the variables. Variable substitution should nearly always be quoted, particularly if the values contain spaces or other reserved shell characters.
Code:
#cp "$pdf" "$destination/$filename"
The exception is, obviously, when you actually want the shell to see and be affected by those reserved characters.
I thank you very much. You suggestions really helped me very much. The renaming happens very precisely. I scheduled the script in crond to find and rename every 3 minutes.
The problem what I face is, while I am saving a pdf file in the source folder and if the script is executed in the same time it creates a errored pdf file in the destination folder.
Rest everything is working fine. Thank You very much once again.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.