Step through directories in Linux

Screenshot of a sample Bash session, taken on ...

This is a post mainly to remind myself how to do something that I discovered after a bit of a dig, but it may come in useful for anyone with a repetitive task to do under Linux.

What I had was a flat set of directories, each with a number of files in. What I wanted to do was to go through these and, where the contents were jpegs, archive them into a zip file and erase the jpegs. Then move the resultant zip file up a level into the parent directory and erase the resulting empty one.

I managed to work out a fairly simple solution, although with one failing – it doesn’t take into account directories which didn’t have jpegs in. What I did was move those which contained non-jpegs (there were no mixtures, in this instance – directories were either 100% jpeg or 100% not) into another folder for safe keeping before I ran the routine. This means I could keep the command as simple as possible.

Do note, though, that I specified “rm *.jpg” rather than moving the zip and deleting the directory contents. Just in case I was wrong and a directory had a non-jpeg in it, I specified jpeg deletion. That way, if something else random was in there I could easily see when the directory couldn’t be deleted. If necessary I could then manually edit the resultant zip file and remove the offending item before manually erasing the directory.

Having said that, it wouldn’t have been dangerous to run it as-is without moving them. The command would simply have created archives I didn’t want, failed to have erased the non-existent jpegs, and therefore not have been able to erase the directories in question. “rmdir” cannot erase a non-empty directory without specific qualifiers (-rf, for instance) so the remaining data would have been safe. And I could simply have deleted the unwanted zips. However, as they were often from folders full of large movie files, this would have slowed down the whole process a lot and also have caused possible hard drive capacity issues.

The resultant command was as follows:

for dir in *;do (cd "$dir"; tar -c -z -f "$dir".zip *; rm *.jpg; mv * ..; cd ..; rmdir "$dir"); done

Note that this can also be re-written as a script. Simply line-break it where it makes sense and ditch the semi-colons. Of course, it can also be used as th ebasis for anything else that involves whipping through a flat directory structure.

Before some UNIX guru tells me my solution is inelegant and nasty, I know you’re probably right. But it did what I need and I’m not an expert! By all means, furnish me with something more professional – I’m always happy to learn.

Reblog this post [with Zemanta]
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x