LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Running a command on all files within a directory (https://www.linuxquestions.org/questions/linux-newbie-8/running-a-command-on-all-files-within-a-directory-754386/)

ls86 09-11-2009 06:13 AM

Running a command on all files within a directory
 
Hi All,

I have a bunch of css and js files that I want to minify.These reside in different directories.

I want to minify them using the YUI compressor.The compressor is a jar file, and it is possible to compress a file using the following command:

java -jar yuicompressor-2.4.2.jar -v -o button.css button.css

here the source file is button.css and I am just overwriting the current contents with the minified contents.

I was wondering if anyone can tell me if given a parent directory how I can recurse through all the sub directories - minifying all the css/js files that I find by applying the above command.

Thanks in advance for any suggestions.

pwc101 09-11-2009 06:21 AM

You'll be wanting the find command:
Code:

find /parent/directory -iname "button.css" -exec java -jar yuicompressor-2.4.2.jar -v -o button.css "{}" \;
I can't test this as I don't have yuicompressor on my systems, but in essence, you find anything whose name matches button.css, then you execute the command you want to apply to the found file using the -exec option. After that, {} represents the found file in the command, and you have to terminate the find command with \;. I'd test the command by adding an echo before the yuicompressor command on some non-mission-critical files first:
Code:

find /parent/directory -iname "button.css" -exec echo java -jar yuicompressor-2.4.2.jar -v -o button.css "{}" \;
This way, it'll spit out the commands to stdout as though you were typing them in manually. This means you can check to make sure it's doing what you expect. Then, when you're happy with the command, take out the echo.

As I said, be careful, because as soon as you whip out the echo, it'll actually start doing things to files. I'd highly recommend having a backup before you start this.

catkin 09-11-2009 06:22 AM

Assuming all the css/js files have extensions .css and .js then try
Code:

/usr/bin/find <top level directory name> -name '*.css' -o -name '*.js' -exec echo <your command> {} \;
The find command replaces {} with the name of each matching file in turn. After testing, when you are confient the find command is generating the required commands, run it again without the "echo".

EDIT: pwc101 got there first while I was typing :)

colucix 09-11-2009 06:26 AM

Recursion can be performed by the command find. A simple way to do that is a loop over the result of the find command, that is a list of all .css and .js files inside the source directory tree. For example:
Code:

while read file
do
  echo java -jar yuicompressor-2.4.2.jar -v -o "$file" "$file"
done < <(find /path/to/parent/dir -type f \( -name \*.css -o -name \*.js \))

Here the find command searches all the files with suffixes .css OR .js under /path/to/parent/dir and passes the list of files to the while loop using process substitution. I deliberately put an echo in front of the java command for testing purposes: the loop will just print out the commands to be executed without actually run them. In this way you can check the sanity of the code and if the result you get matches exactly what do you expect.

Edit: beaten by pwc101 and catkin! Too slow this time! ;)

catkin 09-11-2009 06:43 AM

Quote:

Originally Posted by colucix (Post 3678601)
Edit: beaten by pwc101 and catkin! Too slow this time! ;)

Interesting to reflect on the similarities and differences between the 3 essentially similar solutions. Pwc101 used -iname rather than -name thus picking up any *.CSS *.cSs files etc. Colucix used -type f so we don't mess with any directories, pipes, device files etc. Colucix also used a script which allows easy extensibility for logging etc.

pwc101 09-11-2009 07:00 AM

Using -iname is a habit I've developed, though probably not always a great idea. I should add -type f more frequently as I rarely work with directories in this manner. Still, the solution is likely to be a combination of the three :)

ls86 09-15-2009 12:42 AM

Thank you very much for all your suggestions.Its very encouraging when you get 3 great replies to your very first post.

I found all the suggestions given to be very useful,but I finally went with colucix's suggestion:

while read file
do
echo java -jar yuicompressor-2.4.2.jar -v -o "$file" "$file"
done < <(find /path/to/parent/dir -type f \( -name \*.css -o -name \*.js \))

it was exactly what I wanted


All times are GMT -5. The time now is 12:13 AM.