<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Forward Lateral &#187; bash</title>
	<atom:link href="http://forwardlateral.com/blog/tag/bash/feed/" rel="self" type="application/rss+xml" />
	<link>http://forwardlateral.com/blog</link>
	<description>A nice place to hear myself talk</description>
	<lastBuildDate>Mon, 12 Apr 2010 00:35:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=7434</generator>
		<item>
		<title>Don&#8217;t go there: Keeping the Unix &#8216;find&#8217; command out of your CVS and Subversion directories.</title>
		<link>http://forwardlateral.com/blog/2006/02/27/dont-go-there/</link>
		<comments>http://forwardlateral.com/blog/2006/02/27/dont-go-there/#comments</comments>
		<pubDate>Tue, 28 Feb 2006 06:42:36 +0000</pubDate>
		<dc:creator>Michael Birk</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://forwardlateral.com/blog/2006/02/27/dont-go-there/</guid>
		<description><![CDATA[You&#8217;ve avoided learning the ins-and-outs of the Unix find command because it doesn&#8217;t play nice within your Subversion and CVS working directories? Well then, I&#8217;ve got just the solution! Don&#8217;t want to read my ridiculous blathering? No problem! Just download the free, open source code that &#8220;fixes&#8221; find. This article assumes that you have a [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve avoided learning the ins-and-outs of the Unix <em>find</em> command because it doesn&#8217;t play nice within your Subversion and CVS working directories? Well then, I&#8217;ve got just the solution!</p>
<blockquote><p>Don&#8217;t want to read my ridiculous blathering? No problem! Just <a title="dont-go-there.sh: Keeping the Unix 'find' command out of your CVS and Subversion directories." href="http://forwardlateral.com/dont-go-there.sh">download the free, open source code that &#8220;fixes&#8221; <em>find</em></a>.</p></blockquote>
<p><span id="more-11"></span></p>
<p>This article assumes that you have a basic understanding of Unix and the command-line shell. The software only works with <a href="http://www.gnu.org/software/bash/bash.html">GNU bash</a>.</p>
<p>The Unix <em>find</em> and <em>xargs</em> commands are quite useful for quickly processing files in an entire directory tree. One of the most common idioms is to combine them with <em>grep</em> in order to do a &#8220;recursive grep&#8221; that searches through all of the files in a directory. For example:</p>
<pre lang="bash"><strong>find /path/to/haystack/ -type f | xargs grep needle</strong></pre>
<p>However, this will fail if any of the path names have spaces or other special characters. To fix that problem, use null separators:</p>
<pre lang="bash"><strong>find /path/to/haystack/ -type f -print0 | xargs -0 grep needle</strong></pre>
<p>Usually, the &#8220;haystack&#8221; is simply the current directory. And often, we want to search files with a particular extension, such as <em>.sh</em> files. For example:</p>
<pre lang="bash"><strong>find . -name \*.sh -print0 | xargs -0 grep needle</strong></pre>
<p>Unfortunately, if you run these commands within a <em>working directory</em> &#8212; that is, a directory tree that is managed by a source control system such as CVS or Subversion &#8212; you may get more than you bargained for. That&#8217;s because these systems create special, &#8220;hidden&#8221; directories that you aren&#8217;t supposed to mess with. With Subversion, it is the &#8216;.svn&#8217; directory:</p>
<pre lang="bash"><strong>ls .svn/</strong>
README.txt empty-file format props tmp
dir-props entries prop-base text-base wcprops</pre>
<p>CVS uses a similar directory named, well, CVS.</p>
<p>When you consider that every subdirectory in your working directory tree has its own &#8216;.svn&#8217; (or CVS) directory, it&#8217;s easy to see how this can interfere with your recursive greps and whatnot. What to do?</p>
<p>One idea is to use the power of <em>find</em> to skip over those special directories. Unfortunately, <em>find</em> can be tricky to get right. It turns out that the proper syntax is:</p>
<pre lang="bash"><strong>find . ! ( -name .svn -prune )</strong></pre>
<p>That&#8217;s not too pretty, especially when you consider that ! and ( are special characters in both <em>bash</em> and <em>find</em>. So you&#8217;d better type:</p>
<pre lang="bash"><strong>find . \! \( -name .svn -prune \)</strong></pre>
<p>Clearly that&#8217;s an error-prone burden, particularly once you connect the dots:</p>
<pre lang="bash"><strong>find . \! \( -name .svn -prune \) -name \*.sh -print0 | xargs grep -0 needle</strong></pre>
<p>I&#8217;ve packaged this into a transparent wrapper that tweaks the command line before <em>find</em> sees it, inserting a filter like the one above. And although <em>find</em> has a non-standard syntax that, among other things, places constraints on the ordering of the options, the resulting logic is non-trivial but manageable.</p>
<p>To use this solution, <a title="dont-go-there.sh: Keeping the Unix 'find' command out of your CVS and Subversion directories." href="http://forwardlateral.com/dont-go-there.sh">download the script</a> and place it in your home directory (or anywhere else). Then modify your .bashrc or .bash_profile script to include it:</p>
<pre lang="bash"><strong>source ~/dont-go-there.sh</strong></pre>
<p>The next time you login, the find wrapper function will be in place. To test it, try the new <em>-debug</em> option:</p>
<pre lang="bash"><strong>find -debug . -type f
</strong>find . ! ( ( -name .svn -o -name CVS ) -prune ) -type f</pre>
<p>Note that, if need be, you can bypass the wrapper using the <em>command</em> builtin. In that case, <em>find</em> is invoked directly and the .svn and CVS directories are not treated specially:</p>
<pre lang="bash"><strong>command find . -name .svn</strong></pre>
]]></content:encoded>
			<wfw:commentRss>http://forwardlateral.com/blog/2006/02/27/dont-go-there/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
