<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:admin="http://webns.net/mvcb/"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
	<channel> 

	<title>Comments on: Batch-correct files?</title>
	<link>http://ask.metafilter.com/8335/Batchcorrect-files/</link>
	<description>Comments on Ask MetaFilter post Batch-correct files?</description>
	<pubDate>Tue, 29 Jun 2004 12:50:19 -0800</pubDate>
	<lastBuildDate>Tue, 29 Jun 2004 12:50:19 -0800</lastBuildDate>
	<language>en-us</language>
	<docs>http://blogs.law.harvard.edu/tech/rss</docs>
	<ttl>60</ttl>

	<item>
		<title>Question: Batch-correct files?</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files</link>	
		<description>&lt;b&gt;sed:&lt;/b&gt; How do I use it to do a general search/replace on a bunch of files? The docs seem to believe all I have to do is feed it s/regexp/replacetext/g and a list of files and I&apos;m off to the races, but rather than getting the files changed... &lt;small&gt;[exciting conclusion inside]&lt;/small&gt; &lt;br /&gt;&lt;br /&gt; ... rather than changing the files, it just spits all of the changed lines to stdout.&lt;br&gt;
&lt;br&gt;
So... if file &quot;one&quot; contains:&lt;br&gt;
&lt;br&gt;
the quick brown fox jumped over the lazy dog&lt;br&gt;
&lt;br&gt;
and file &quot;two&quot; contains:&lt;br&gt;
&lt;br&gt;
the grove of trees was interesting&lt;br&gt;
&lt;br&gt;
Then: &lt;code&gt;sed s/the/an/g *&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
gives me:&lt;br&gt;
&lt;br&gt;
an quick brown fox jumped over an lazy dog&lt;br&gt;
an ash grove&lt;br&gt;
&lt;br&gt;
Which would be great if I wanted to concatenate all the results into a single file, but I don&apos;t. I want the changed results to sit in their source files. Without resulting to something like &lt;code&gt;find . -exec sed s/the/an/gw{} {} \; -freak -I -dont -understand -unix&lt;/code&gt;.&lt;br&gt;
&lt;br&gt;
Of course, I&apos;d also like world peace and a pony.</description>
		<guid isPermaLink="false">post:ask.metafilter.com,2004:site.8335</guid>
		<pubDate>Tue, 29 Jun 2004 12:34:05 -0800</pubDate>
		<dc:creator>namespan</dc:creator>
		
			<category>sed</category>
		
			<category>search</category>
		
			<category>replace</category>
		
			<category>editing</category>
		
			<category>text</category>
		
			<category>unix</category>
		
			<category>nix</category>
		
	</item> <item>
		<title>By: greasepig</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161575</link>	
		<description>&lt;code&gt;perl -pi -e &apos;s|foo|bar|g&apos; *&lt;/code&gt;</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161575</guid>
		<pubDate>Tue, 29 Jun 2004 12:50:19 -0800</pubDate>
		<dc:creator>greasepig</dc:creator>
	</item><item>
		<title>By: namespan</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161583</link>	
		<description>Thanks greasepig! This alleviates the pressure of my practical needs ... however, I&apos;m still curious about how sed is supposed to do what it does...</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161583</guid>
		<pubDate>Tue, 29 Jun 2004 13:17:59 -0800</pubDate>
		<dc:creator>namespan</dc:creator>
	</item><item>
		<title>By: mragreeable</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161591</link>	
		<description>Well, sed is doing what it&apos;s &lt;i&gt;supposed&lt;/i&gt; to do, which is process a stream.  It doesn&apos;t really think about files as such.&lt;br&gt;
&lt;br&gt;
A simple way to do what you want with sed would be this:&lt;br&gt;
&lt;br&gt;
&lt;code&gt;mkdir ../processed&lt;br&gt;
find . -exec sh -c &quot;cat {} | sed -e &apos;s/frank/howard/g&apos; &amp;gt; ../processed/{}&quot; \;&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
That will make a copy of all of the files to be processed in a directory called &quot;processed.&quot;  Having sed overwrite the files as its processing them isn&apos;t an option, so it has to write to somewhere different.  You could make that a more complicated one-liner and have it rename the file first, have sed do its thing to a new file with the original name and delete the newly renamed version.  Also, be sure not to have the copies of the files go into a directory that &lt;code&gt;find&lt;/code&gt; will find, or it will recurse forever.  (Or until your hard drive is full.)</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161591</guid>
		<pubDate>Tue, 29 Jun 2004 13:30:49 -0800</pubDate>
		<dc:creator>mragreeable</dc:creator>
	</item><item>
		<title>By: sfenders</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161630</link>	
		<description>With gnu sed (which is what your average Linux machine has), you can just use the -i option:&lt;br&gt;
&lt;br&gt;
sed -i &apos;s/foo/bar/g&apos; *</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161630</guid>
		<pubDate>Tue, 29 Jun 2004 15:36:51 -0800</pubDate>
		<dc:creator>sfenders</dc:creator>
	</item><item>
		<title>By: namespan</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161665</link>	
		<description>sfenders, that&apos;s awesome.&lt;br&gt;
&lt;br&gt;
mragreeable.... out of curiousity, how come the cat/sed command is encased in the sh -c part? I understand the rest of the find command except for that part.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161665</guid>
		<pubDate>Tue, 29 Jun 2004 17:56:08 -0800</pubDate>
		<dc:creator>namespan</dc:creator>
	</item><item>
		<title>By: mragreeable</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161718</link>	
		<description>Yeah, sfenders gets the award, I think.&lt;br&gt;
&lt;br&gt;
As for the other question, &lt;code&gt;find&lt;/code&gt; will run a single program when using &lt;code&gt;-exec&lt;/code&gt;.  If it sees something like &quot;|&quot; or &quot;&amp;gt;&quot; it won&apos;t interpret them for you, it will just pass them as parameters to the command it&apos;s running.  So I use &lt;code&gt;sh -c&lt;/code&gt;, and have bash (or whatever) interpret the shell symbols for me.  When using that technique it&apos;s usually a good idea to put the {} symbol in single-quotes if there&apos;s a chance that the filenames will have spaces.&lt;br&gt;
&lt;br&gt;
At least that&apos;s been my finding.  If someone knows of a way to use pipes and stuff with &lt;code&gt;find&lt;/code&gt; without using a similar technique, I&apos;d love to hear about it.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161718</guid>
		<pubDate>Tue, 29 Jun 2004 20:16:54 -0800</pubDate>
		<dc:creator>mragreeable</dc:creator>
	</item><item>
		<title>By: sfenders</title>
		<link>http://ask.metafilter.com/8335/Batchcorrect-files#161761</link>	
		<description>Using find, and pretending sed -i doesn&apos;t exist, I&apos;d do it like this:&lt;br&gt;
&lt;br&gt;
for i in `find . -type f` ; do cat $i | sed &apos;s,xxx,yy,g&apos; &amp;gt; .$i.tmp ; mv .$i.tmp $i; done</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2004:site.8335-161761</guid>
		<pubDate>Tue, 29 Jun 2004 21:57:18 -0800</pubDate>
		<dc:creator>sfenders</dc:creator>
	</item>
	</channel>
</rss>
