Here's another solution to the common scripting problem of adapting ls output for use by other commands ... solved with a (very) little PHP!
So I'm using tar to create a simple backup for a web site. Only now the website has podcasts, and I don't need to back those up. I've got a copy elsewhere, and they dwarf the size of the original site.
tar lets me specify a whole set of files and folders, so that's not the problem. I just want an automated way to specify "everything, but not this and not that." I can use ls to get a list of files, but how do I remove just a few programmatically, and how do I get ls to return the full path?
To get the list of all files in my public_html folder, one per line:
ls -a1 $HOME/public_html
To get the path to my public_html folder:
ls -d $HOME/public_html
Now, if I pipe the file names to a PHP script, and pass in the parent folder as an argument, I can use PHP to generate the full path and also selectively cull out items I don't want (including '.' and '..', which ls includes unconditionally). The -R flag runs the PHP script once for each line in the input. Very convenient.
ls -a1 $HOME/public_html | \ php -R \ 'if(!in_array($argn, array(".","..","podcasts"))) echo $argv."/".$argn."\n";' \ $(ls -d $HOME/public_html)$argv contains the command-line arguments. $argn is the line from stdin.
The completed command looks like this. It seems like there ought to be a simpler way, but this works, and I will still be able to read this next time I need to modify the script. Neat.
tar -czf $HOME/backups/web-$(date +%Y-%m-%d).tar.gz \ $(ls -a1 $HOME/public_html | \ php -R \ 'if(!in_array($argn, array(".","..","podcasts"))) echo $argv."/".$argn."\n";' \ $(ls -d $HOME/public_html))