I’m looking to write a bash script that will recursively find all .less files in a directory and create a .css file with the same name in a parent css directory using lessc. Visually it looks like this.
Before:
/css
/less
a.less
b.less
/whatever
/css
/less
c.less
d.less
After:
/css
a.css
b.css
/less
a.less
b.less
/whatever
/css
c.css
d.css
/less
c.less
d.less
What I’ve been able to figure out so far is that I can find all the files using:
find . -name *.less
And I can generate individual files using:
lessc foo.less > ../css/foo.css
My problem comes trying to pipe the results of the find into lessc. Per this question I can see how the results of find can be piped into cat, but the same approach isn’t working for me with lessc.
In general I’m just having trouble putting the pieces together. Any help would be appreciated.
Thanks.
Edit
This is what worked for me. Thanks @ghoti!
find . -name \*.less -print | sed -rne 's:(.*)/less/([^/]+).less$:lessc & > \1/css/\2.css:p' | sh
You’ve got all the ingredients. You just need the recipe. 🙂
And there are multiple recipes.
Normally, you can use
find‘s-execoption to execute things based on what it finds. However, you’re limited in what you can name things. For example, if you were to use this:you would create files in a css directory in the parent from where find is running, and files would be named things like a.less.css, b.less.css, etc. That’s not good. You’d need to embed
dirnameand such into your command, and then things get impossible to manage, with too many quotes and backslashes.When I have to do pattern-matting AND changes like this, I often resort to pipes. Here’s what I’d do:
The
findgets your files, as you’d expect. Then thesedscript turns them into command lines. The output of this is a collection oflessccommand lines which you can simply pipe intoshonce you’ve verified that they look right.Here are the results.
Before:
Then the test run:
Then the final run, and results.
For my test, I replaced
lesscwithcat, since less isn’t installed on my workstation.Note that this will only work with simple filenames like the ones in your example. If you have spaces or possibly other “special” characters, it will break.