Linux Newbie with issues with find
I've got almost 20 years working with computers. It's all been with Windows/DOS machines, though. Now I find myself with a Linux flavored NAs and having issues getting things working the way I've wanted.
Some things I have had issues with, I've found answers for here. (cronjobs to keep a drive enclosure alive, scripting to check an application.) Other things I've had some problems finding information on. Specifically, I'm downloading files from a local server. Some of these files are pdf's, others are text, docs, etc. They are all placed in /download. Sometimes in that folder, sometimes in folders under it. (/download/testing/, various other folders, each named uniquely.) I think there must be a way to check recursively within a folder and find the files by extension, move those with *,pdf into a folder so they don't need to be worked on. Move the others into a folder like /volume1/needswork/ so those can be checked, modified and converted to pdf. I know this would be a 2 step or more process, and need to check the original folder on approximately an hourly basis, movee the files, and go on. I expect this is a rather complex set of commands. I have already tested this command in the folder looking for it. It doesn't work. (-exec needs an argument) find . \( -name "/download/*.pdf" \) -exec mv {} /volume1/USB1/checked/ \; Am I missing something here? Thanks in advance. Mike |
bash spits out a warning on my Debian box using the command that you posted:
Quote:
Code:
find . -wholename ./download/*.pdf -exec mv {} checked/ \; |
As you have a 2 part process which find would not be able to do, ie pdf files here and other files elsewhere, I would write it as a script.
Something simple like below to get you started: Code:
#!/usr/bin/env bash I have used a case statement for a little future proofing being that you might end up with several extensions and place them in alternate locations If you wanted to you could also spiffy it up a little by using associative arrays which would void the case being required. |
Grail,
Your solution brings up almost as many questions as it does answers.... :) I have NO scripting experience, and this smacks more like actual programming than anything in batch files associated with DOS. So I look at what you have and stare in wonder... :) First is, how is path_to_file set? initial_dir, etc are all preset in the script? ie I replace the $1 with the actual path, or? This would get dropped into the init.d folder and named something like S##ChckMov.sh and then a cronjob added? So far, I've copied/pasted from a couple of sources to get scripts running to check if an app is hung on the NAS. This was something I barely understood the workings of. Your script I think I understand except the points mentioned above. Thanks for taking the time. Mike |
It's an interesting problem. If I may state it again to make sure I understand:
My style would be to determine the two commands to accomplish this and in my case the easier ones would be the find and exec manner and also mv. And then figure out how to do this once per hour. It'll probably be something commented on, but I've run scripts which run forever in a loop, usually to test things and so I put in a sleep 1s into them. Unsure if just running a script and putting in sleep 60s would be considered bad, but that would be my first attempt; which is brute force, before I began to refine. I'd also move all files first and then find only PDF files in the moved to location and re-move those to the checked directory. Why? I'd be concerned that files entered after I checked for and moved PDF files and then next went to move the rest; also given that "the rest" are "any" types of files and/or directories, so in that second case, I'm not searching for specific extensions or names, pretty much just any files. Haven't run this, but the general gist of my first attempt would be a bash script: Code:
#!/bin/sh I would run a script like that in the testing phase from a terminal and then I could echo status information; however the set -xv part will cause the script to output debug. It will be helpful to test what it's doing against the flow of data entering into your /download directory. As far as zero sized files, incomplete files, or temporary files; you can instead of the broad brushed "mv" command you can find a way to detect non-zero sized files and not move them. If sub-directories are associated with certain files; a'la complete web site saves; then saem thing, detect a zero sized HTML file, detect the associated directory, and don't move both of those. This is obviously more sophisticated than a simple fine, but that's what refinement is all about. And finally temporary files; for instance you're downloading a very large XZ file, say a disk image; you'll have the XZ file there, but also have something like ....xz.temp which will be a temporary file that grows as you download and ends up being renamed or copied into the intended save file name. You can detect the zero sized file as well as the temp file and determine that you don't wish to move them until the download is complete, or rather some future loop iteration where this condition no longer exists. All that about unresolved files I'd say is refinement, just IMHO. |
You have the process that I'm trying to get to down pat. I'm liking the idea trains this thread is going down. :)
All of the files I would be searching for, in their downloaded state, are going to have an extension of .part. They are downloaded via torrent from the server to the NAS, and partial files would have a name like "abcxyz.pdf.part". Once the file is completed the .part comes off and the file name reverts to "abcxyz.pdf" as named on the server. Since we aren't looking for a contains pdf but ends pdf this should work quite well. I will run some tests. Looking at your script, if the files are in a sub, will that sub be created in the new location? Even if they are pdf's? Or will the pdf's get moved into the parent /watched folder? (I'll ditz with this, too...) :) Also could I include another while loop to check for each extension .txt, .doc, etc... One for each, right? Don't move everything, but just the ones I want, when all of the .parts are done, delete the extra, extraneous stuff? Modifying the script you provided: Code:
#!/bin/sh |
Quote:
Code:
while [ 1 == 1 ]; do If you want to execute a command every minute, cron could do that. |
Personally, I would prefer to use inotifywait to put a watch on the download directory and move files when they are closed.
Pinching grail's code I came up with this Code:
#!/bin/bash |
I wasn't aware of the requirement to run this from cron or so on, but thought I would help you understand the code a little :)
First point would be that actually yes a bash script is similar in use to a windows batch script but the level of power in what can be done is considerably more. First point is that as I thought it was a script you would be calling as a user, the $1, $2, etc used in the script are parameters passed to the script at point of running. So it would look something like: Code:
$ ./process_downloads.sh /download /needswork /checked Code:
#!/usr/bin/env bash Quote:
My thinking here is that once the '.part' is removed will be the only time we need to move a file and at this point we are also saying that the file has now finished any processing / downloading (I may be wrong and am sure allend will let us know :) ) So you can alter the above to include your new extensions like so: Code:
#!/usr/bin/env bash |
Just want to say the I have edited my original post in this thread to remove some inaccurate comments in the code that I missed when I did a copy and paste from an earlier LQ post. I have also added a line to cover the creation of .part files. My intention was to demonstrate an alternative method for the OP to consider.
@OP Do as grail says. I would never presume that I could improve on what grail presents. That post to reputation points ratio is well deserved. |
As Beryllos points out the loop is forever so will not break out. Therefore also the second and third loops won't be run, you could do it differently such as:
Code:
while [ 1 == 1 ]; do HOWEVER!!!! Sorry for the bold but intending to get your attention: Quote:
And further, there are much more elegant and more well versed script writers offering comments. Similarly their suggestions go over my experience level, but worth looking at providing you can understand how the script ultimately does work. |
All times are GMT -5. The time now is 01:25 AM. |