<?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>Mark Needham &#187; Shell Scripting</title>
	<atom:link href="http://www.markhneedham.com/blog/category/shell-scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.markhneedham.com/blog</link>
	<description>Thoughts on Software Development</description>
	<lastBuildDate>Sat, 11 Feb 2012 10:56:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Learning Unix find: Searching in/Excluding certain folders</title>
		<link>http://www.markhneedham.com/blog/2011/10/21/learning-unix-find-searching-inexcluding-certain-folders/</link>
		<comments>http://www.markhneedham.com/blog/2011/10/21/learning-unix-find-searching-inexcluding-certain-folders/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 21:25:04 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell-scripting]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3754</guid>
		<description><![CDATA[I love playing around with commands on the Unix shell but one of the ones that I&#8217;ve found the most difficult to learn beyond the very basics is find. I think this is partially because I find the find man page quite difficult to read and partially because it&#8217;s usually quicker to work out how [...]]]></description>
			<content:encoded><![CDATA[<p>I love playing around with commands on the Unix shell but one of the ones that I&#8217;ve found the most difficult to learn beyond the very basics is <cite><a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?find">find</a></cite>.</p>
<p>I think this is partially because I find the find man page quite difficult to read and partially because it&#8217;s usually quicker to work out how to solve my problem with a command I already know than to learn another one.</p>
<p>However, I recently came across <a href="http://mywiki.wooledge.org/UsingFind">Greg&#8217;s wiki</a> which seems to do a pretty good job of explaining it.</p>
<p>Reasonably frequently I want to get a list of files to scan but want to exclude files in the .git directory since the results tend to become overwhelming with those included:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ find . ! -path  &quot;*.git*&quot; -type f -print</pre></div></div>

<p>Here we&#8217;re saying find items which don&#8217;t have git in their path and which are of type &#8216;f&#8217; (file) and then print them out.</p>
<p>If we don&#8217;t include the <cite>-type</cite> flag then the results will also include directories which isn&#8217;t what we want in this case. The <cite>-print</cite> is optional in this case since by default what we select will be printed.</p>
<p>Sometimes we want to exclude more than one directory which can be done with the following command:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ find . \( ! -path &quot;*target*&quot; -a ! -path &quot;*tools*&quot; -a ! -path &quot;*.git*&quot; -print \)</pre></div></div>

<p>Here we&#8217;re excluding the &#8216;target&#8217;, &#8216;tools&#8217; and &#8216;git&#8217; directories from the listing of files that we return.</p>
<p>The <cite>-a</cite> flag stands for &#8216;and&#8217; so the above command reads &#8216;find all files/directories which do not have target in their path and do not have tools in their path and do not have .git in their path&#8217;. </p>
<p>We can always make that command a bit more specific if any of those words legitimately appear in a path.</p>
<p>As well as the <cite>-print</cite> flag there is also a <cite>-prune</cite> flag which we can use to stop find from descending into a folder.</p>
<p>The first command could therefore be written like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ find . -path &quot;*.git*&quot; -prune -o -type f -print</pre></div></div>

<p>This reads &#8216;don&#8217;t go any further into a folder which has git in the path but print any other files which don&#8217;t have git in their path&#8217;.</p>
<p>I&#8217;m still finding <cite>-prune</cite> a bit confusing to understand and as the wiki points out:</p>
<blockquote><p>
The most confusing property of -prune is that it is an ACTION, and thus no further filters are processed after it.</p>
<p>To use it, you have to combine it with -o to actually process the non-skipped files, like so:
</p></blockquote>
<p>A couple of months ago I was playing around with our git repository trying to get a list of all the scala files in the &#8216;src/main&#8217; directory and I went with this command:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ find . -type f -regex &quot;.*src/main.*\.scala$&quot;</pre></div></div>

<p>Using the above flags it could instead be written like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ find . -path &quot;*src/main*&quot; -type f -iname &quot;*\.scala*&quot;</pre></div></div>

<p>or</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ find . -type f -path &quot;*src/main/*\.scala&quot;</pre></div></div>

<p>Interestingly those latter two versions seem to be a bit slower than the one that uses the <cite>-regex</cite> flag.</p>
<p>I&#8217;m not entirely sure why that is &#8211; presumably by supplying two flags on the latter two solutions <cite>find</cite> has to do more operations per line than it does with the <cite>-regex</cite> option or something like that?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/10/21/learning-unix-find-searching-inexcluding-certain-folders/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Bash: Reusing previous commands</title>
		<link>http://www.markhneedham.com/blog/2011/10/13/bash-reusing-previous-commands/</link>
		<comments>http://www.markhneedham.com/blog/2011/10/13/bash-reusing-previous-commands/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 19:46:20 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3744</guid>
		<description><![CDATA[A lot of the time when I&#8217;m using the bash shell I want to re-use commands that I&#8217;ve previously entered and I&#8217;ve recently learnt some neat ways to do this from my colleagues Tom and Kief. If we want to list the history of all the commands we&#8217;ve entered in a shell session then the [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of the time when I&#8217;m using the bash shell I want to re-use commands that I&#8217;ve previously entered and I&#8217;ve recently learnt some neat ways to do this from my colleagues <a href="http://twitter.com/#!/tomduckering">Tom</a> and <a href="http://twitter.com/kief">Kief</a>.</p>
<p>If we want to list the history of all the commands we&#8217;ve entered in a shell session then the following command does the trick:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; history
...
  761  sudo port search pdfinfo
  762  to_ipad andersen-phd-thesis.pdf 
  763  vi ~/.bash_profile
  764  source ~/.bash_profile
  765  to_ipad andersen-phd-thesis.pdf 
  766  to_ipad spotify-p2p10.pdf 
  767  mkdir LinearAlgebra</pre></div></div>

<p>If we want to execute any of those commands again then we can do that by entering <cite>![numberOfCommand</cite>. For example, to execute the last command on that list we&#8217;d do this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; !767
mkdir LinearAlgebra
mkdir: LinearAlgebra: File exists</pre></div></div>

<p>We can also search the history and execute the last command that matches the search by doing the following:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; !mk
mkdir LinearAlgebra
mkdir: LinearAlgebra: File exists</pre></div></div>

<p>A safer way to do this would be to suffix that with <cite>:p</cite> so the command gets printed to stdout rather than executed:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; !mk:p
mkdir LinearAlgebra</pre></div></div>

<p>A fairly common use case that I&#8217;ve come across is to search for a file and then once you&#8217;ve found it open it in a text editor. </p>
<p>We can do this by using the <cite>!!</cite> command which repeats the previously executed command:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; find . -iname &quot;someFile.txt&quot;
&gt; vi `!!`</pre></div></div>

<p>We can achieve the same thing by wrapping &#8216;!!&#8217; inside &#8216;$()&#8217; as well:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; find . -iname &quot;someFile.txt&quot;
&gt; vi $(!!)</pre></div></div>

<p>Sam Rowe has a cool post where he <a href="http://samrowe.com/wordpress/advancing-in-the-bash-shell/">goes into this stuff in even more detail</a>.</p>
<p>I&#8217;m sure there are more tricks that I haven&#8217;t learnt yet so please let me know if you know some!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/10/13/bash-reusing-previous-commands/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Unix: Getting the page count of a linearized PDF</title>
		<link>http://www.markhneedham.com/blog/2011/10/09/unix-getting-the-page-count-of-a-linearized-pdf/</link>
		<comments>http://www.markhneedham.com/blog/2011/10/09/unix-getting-the-page-count-of-a-linearized-pdf/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 11:34:04 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3740</guid>
		<description><![CDATA[We were doing some work last week to rasterize a PDF document into a sequence of images and wanted to get a rough idea of how many pages we&#8217;d be dealing with if we created an image per page. The PDFs we&#8217;re dealing with are linearized since they&#8217;re available for viewing on the web: A [...]]]></description>
			<content:encoded><![CDATA[<p>We were doing some work last week to rasterize a PDF document into a sequence of images and wanted to get a rough idea of how many pages we&#8217;d be dealing with if we created an image per page.</p>
<p>The PDFs we&#8217;re dealing with are <a href="http://partners.adobe.com/public/developer/en/pdf/PDFReference.pdf">linearized</a> since they&#8217;re available for viewing on the web:</p>
<blockquote><p>
A LINEARIZED PDF FILE is one that has been organized in a special way to enable efﬁcient incremental access in a network environment. </p>
<p>The ﬁle is valid PDF in all respects, and is compatible with all existing viewers and other PDF applications. Enhanced viewer applications can recognize that a PDF ﬁle has been linearized and can take advantage of that organization (as well as added “hint” information) to enhance viewing performance.
</p></blockquote>
<p>The neat thing about this is it means that the document has meta data detailing the number of pages it contains:</p>
<blockquote><p>
Part 2: Linearization parameter dictionary<br />
<br /> 43 0 obj<br />
<br /> << /Linearized 1.0 % Version<br />
<br /> /L 54567 % File length<br />
<br />/H [475 598] % Primary hint stream offset and length (part 5)<br />
<br />/O 45 % Object number of ﬁrst page’s page object (part 6)<br />
<br /> /E 5437 % Offset of end of ﬁrst page<br />
<br /> <strong>/N 11 % Number of pages in document</strong><br />
<br /> /T 52786 % Offset of ﬁrst entry in main cross-reference table (part 11)<br />
<br /> >><br />
<br /> endobj
</p></blockquote>
<p>By making use of the <cite><a href="http://en.wikipedia.org/wiki/Strings_(Unix)">strings</a></cite> command <a href="http://duncan-cragg.org/blog/">Duncan</a> and I hacked together a little script that lets us grab the number of pages in <a href="http://www.rand.org/pubs/commercial_books/CB149-1.html">The Games of Strategy</a> <a href="http://www.rand.org/content/dam/rand/pubs/commercial_books/2007/RAND_CB149-1.pdf">PDF</a> or any other linearized PDF:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">strings RAND_CB149-1.pdf | 
awk '/Linearized/ { inmeta = 1; } match($0, /\/N [0-9]+/) { if(inmeta) print substr( $0, RSTART, RLENGTH ); exit;}' |
cut -d&quot; &quot; -f2</pre></div></div>

<p>It seems much more difficult to find the count if the document hasn&#8217;t been linearized but we didn&#8217;t need to solve that problem for the moment!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/10/09/unix-getting-the-page-count-of-a-linearized-pdf/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Unix: Summing the total time from a log file</title>
		<link>http://www.markhneedham.com/blog/2011/07/27/unix-summing-the-total-time-from-a-log-file/</link>
		<comments>http://www.markhneedham.com/blog/2011/07/27/unix-summing-the-total-time-from-a-log-file/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 23:02:33 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3687</guid>
		<description><![CDATA[As I mentioned in my last post we&#8217;ve been doing some profiling of a data ingestion job and as a result have been putting some logging into our code to try and work out where we need to work on. We end up with a log file peppered with different statements which looks a bit [...]]]></description>
			<content:encoded><![CDATA[<p>As I <a href="http://www.markhneedham.com/blog/2011/07/27/a-crude-way-of-telling-if-a-remote-machine-is-a-vm/">mentioned in my last post</a> we&#8217;ve been doing some profiling of a data ingestion job and as a result have been putting some logging into our code to try and work out where we need to work on.</p>
<p>We end up with a log file peppered with different statements which looks a bit like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">18:50:08.086 [akka:event-driven:dispatcher:global-5] DEBUG - Imported document. /Users/mneedham/foo.xml in: 1298
18:50:09.064 [akka:event-driven:dispatcher:global-1] DEBUG - Imported document. /Users/mneedham/foo2.xml in: 798
18:50:09.712 [akka:event-driven:dispatcher:global-4] DEBUG - Imported document. /Users/mneedham/foo3.xml in: 298
18:50:10.336 [akka:event-driven:dispatcher:global-3] DEBUG - Imported document. /Users/mneedham/foo4.xml in: 898
18:50:10.982 [akka:event-driven:dispatcher:global-1] DEBUG - Imported document. /Users/mneedham/foo5.xml in: 12298</pre></div></div>

<p>I can never quite tell which column I need to get so end up doing some exploration with awk like this to find out:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ cat foo.log | awk ' { print $9 }'
1298
798
298
898
12298</pre></div></div>

<p>Once we&#8217;ve worked out the column then we can add them together like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ cat foo.log | awk ' { total+=$9 } END { print total }'
15590</pre></div></div>

<p>I think that&#8217;s much better than trying to determine the total run time in the application and printing it out to the log file.</p>
<p>We can also calculate other stats if we record a log entry for each record:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ cat foo.log | awk ' { total+=$9; number+=1 } END { print total/number }'
3118</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ cat foo.log | awk 'min==&quot;&quot; || $9 &lt; min {min=$9; minline=$0}; END{ print min}' 
298</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/07/27/unix-summing-the-total-time-from-a-log-file/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>mount_smbfs: mount error..File exists</title>
		<link>http://www.markhneedham.com/blog/2011/01/15/mount_smbfs-mount-error-file-exists/</link>
		<comments>http://www.markhneedham.com/blog/2011/01/15/mount_smbfs-mount-error-file-exists/#comments</comments>
		<pubDate>Sat, 15 Jan 2011 18:31:07 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell-scripting]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3288</guid>
		<description><![CDATA[I&#8217;ve been playing around with mounting a Windows file share onto my machine via the terminal because I&#8217;m getting bored of constantly having to go to Finder and manually mounting it each time! After a couple of times of mounting and unmounting the drive I ended up with this error: &#62; mount_smbfs //mneedham@punedc02/shared punedc02_shared/ mount_smbfs: [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with mounting a Windows file share onto my machine via the terminal because I&#8217;m getting bored of constantly having to go to Finder and manually mounting it each time!</p>
<p>After a couple of times of mounting and unmounting the drive I ended up with this error:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; mount_smbfs //mneedham@punedc02/shared punedc02_shared/
mount_smbfs: mount error: /Volumes/punedc02_shared: File exists</pre></div></div>

<p>I originally thought the &#8216;file exists&#8217; part of the message was suggesting that I&#8217;d already mounted a share on &#8216;punedc02_shared&#8217; but calling the &#8216;umount&#8217; command led to the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; umount punedc02_shared
umount: punedc02_shared: not currently mounted</pre></div></div>

<p>I had actually absent mindedly gone and mounted the drive elsewhere through Finder which I only realised after reading <a href="http://www.cmsimike.com/blog/2009/06/30/os-x-failure-mounting-via-shell/comment-page-1/#comment-7714">Victor&#8217;s comments on this post</a>.</p>
<blockquote><p>
Make sure that you already do not have the same share mounted on your Mac.</p>
<p>I had //host/share already mounted in /Volumes/share, so when I tried to mount //host/share to /Volumes/newshare it gave me the “file exists” error.
</p></blockquote>
<p>I learnt, thanks to the <a href="http://www.unix.com/71392-post2.html">unix.com forums</a>, that you can see which devices are mounted by using &#8216;df&#8217;.</p>
<p>This is where Finder had mounted the drive for me:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; df
Filesystem                 512-blocks      Used  Available Capacity  Mounted on
...
//mneedham@punedc02/shared  209696376 199773696    9922680    96%    /Volumes/shared</pre></div></div>

<p>Since the shared drive gets unmounted when I disconnect from the network I decided to write a shell script that would set it up for me again.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">#!/bin/sh
function mount_drive {
  mkdir -p $2
  mount_smbfs $1 $2 
}
&nbsp;
drives_to_unmount=`df | awk '/mneedham@punedc02/ { print $6 }'`
&nbsp;
if [ &quot;$drives_to_unmount&quot; != &quot;&quot; ]; then
  echo &quot;Unmounting existing drives on punedc02: \n$drives_to_unmount&quot;
  umount $drives_to_unmount
fi
&nbsp;
mount_drive //mneedham@punedc02/media /Volumes/punedc02_media 
mount_drive //mneedham@punedc02/shared /Volumes/punedc02_shared</pre></div></div>

<p>At the moment I&#8217;ve just put that in &#8216;/usr/bin&#8217; so that it&#8217;s available on the path.</p>
<p>If there&#8217;s a better way to do this or a way to simplify the code please let me know.</p>
<p>I did come across a few ways to do the mounting using Apple Script in <a href="http://hints.macworld.com/article.php?story=20020610225855377">this post</a> but that&#8217;s not half as fun as using the shell!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/01/15/mount_smbfs-mount-error-file-exists/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sed: &#8216;sed: 1: invalid command code R&#8217; on Mac OS X</title>
		<link>http://www.markhneedham.com/blog/2011/01/14/sed-sed-1-invalid-command-code-r-on-mac-os-x/</link>
		<comments>http://www.markhneedham.com/blog/2011/01/14/sed-sed-1-invalid-command-code-r-on-mac-os-x/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 14:15:19 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell-scripting]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3285</guid>
		<description><![CDATA[A few days ago I wrote about how we&#8217;d been using Sed to edit multiple files and while those examples were derived from what we&#8217;d been using on Ubuntu I realised that they didn&#8217;t actually work on Mac OS X. For example, the following command: sed -i 's/require/include/' Rakefile Throws this error: sed: 1: &#34;Rakefile&#34;: [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I wrote about how we&#8217;d been <a href="http://www.markhneedham.com/blog/2011/01/11/sed-across-multiple-files/">using Sed to edit multiple files</a> and while those examples were derived from what we&#8217;d been using on Ubuntu I realised that they didn&#8217;t actually work on Mac OS X.</p>
<p>For example, the following command:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sed -i 's/require/include/' Rakefile</pre></div></div>

<p>Throws this error:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sed: 1: &quot;Rakefile&quot;: invalid command code R</pre></div></div>

<p>What I hadn&#8217;t realised is that on the Mac version of sed the &#8216;-i&#8217; flag has a mandatory suffix, <a href="http://hintsforums.macworld.com/showpost.php?p=393450&#038;postcount=11">as described in this post</a>.</p>
<p>The appropriate section of the man page for sed on the Mac looks like this:</p>
<blockquote><p>
  -i extension</p>
<p>Edit files in-place, saving backups with the specified extension.  If a zero-length extension is given, no backup will be saved.  </p>
<p>It is not recommended togive a zero-length extension when in-place editing files, as you risk corruption or partial content in situations where disk space is exhausted, etc.
</p></blockquote>
<p>Whereas on Ubuntu the suffix is optional so we see this:</p>
<blockquote><p>
-i[SUFFIX], &#8211;in-place[=SUFFIX]</p>
<p>edit files in place (makes backup if extension supplied)
</p></blockquote>
<p>In order to get around this we need to provide a blank suffix when using the &#8216;-i&#8217; flag on the Mac:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sed -i &quot;&quot; 's/require/include/' Rakefile</pre></div></div>

<p>I didn&#8217;t <a href="http://en.wikipedia.org/wiki/RTFM">RTFM</a> closely enough the first time! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/01/14/sed-sed-1-invalid-command-code-r-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Sed across multiple files</title>
		<link>http://www.markhneedham.com/blog/2011/01/11/sed-across-multiple-files/</link>
		<comments>http://www.markhneedham.com/blog/2011/01/11/sed-across-multiple-files/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 16:43:53 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell-scripting]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3266</guid>
		<description><![CDATA[Pankhuri and I needed to rename a method and change all the places where it was used and decided to see if we could work out how to do it using sed. We needed to change a method call roughly like this: home_link&#40;current_user&#41; To instead read: homepage_path For which we need the following sed expression: [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pankhurisa.blogspot.com/">Pankhuri</a> and I needed to rename a method and change all the places where it was used and decided to see if we could work out how to do it using sed.</p>
<p>We needed to change a method call roughly like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">home_link<span style="color:#006600; font-weight:bold;">&#40;</span>current_user<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>To instead read:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">homepage_path</pre></div></div>

<p>For which we need the following sed expression:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sed -i 's/home_link([^)]*)/homepage_path/' [file_name]</pre></div></div>

<p>Which works pretty well if you know which file you want to change but we wanted to run it over the whole code base.</p>
<p>A bit of googling led us to <a href="http://forums.devshed.com/unix-help-35/how-to-use-sed-to-search-replace-files-throughout-a-184662.html">this thread on devshed</a> which suggested we&#8217;d need to get a list of the files and then run sed through the list:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">for file in `find .  -type f`; do sed -i 's/home_link([^)]*)/homepage_path/' $file; done</pre></div></div>

<p>That pretty much works but it doesn&#8217;t play nicely if the file has a space in the name since sed thinks the file name has ended before it actually has.</p>
<p>I was pretty sure that we should be able to pipe the output of the find into xargs and a bit more googling led us to the following solution:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">find . -type f -print0 | xargs -0 sed -i 's/home_link([^)]*)/homepage_path/'</pre></div></div>

<p>The &#8216;print0&#8242; flag is described like so:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">This primary always evaluates to true.  It prints the pathname of the current file to standard output, followed by an ASCII NUL character (character code 0).</pre></div></div>

<p>While &#8216;-0&#8242; in &#8216;xargs&#8217; is described like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">  -0      Change xargs to expect NUL (``\0'') characters as separators, instead of spaces and newlines.  This is expected to be used in concert with the -print0 function in find(1).</pre></div></div>

<p>It also runs amazingly fast!</p>
<p>If anyone knows a better way feel free to point it out in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2011/01/11/sed-across-multiple-files/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>A dirty hack to get around aliases not working in a shell script</title>
		<link>http://www.markhneedham.com/blog/2010/11/24/a-dirty-hack-to-get-around-aliases-not-working-in-a-shell-script/</link>
		<comments>http://www.markhneedham.com/blog/2010/11/24/a-dirty-hack-to-get-around-aliases-not-working-in-a-shell-script/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 18:48:25 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell-scripting]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=3156</guid>
		<description><![CDATA[In another script I&#8217;ve been working on lately I wanted to call &#8216;mysql&#8217; but unfortunately on my machine it&#8217;s &#8216;mysql5&#8242; rather than &#8216;mysql&#8217;. I have an alias defined in &#8216;~/.bash_profile&#8217; so I can call &#8216;mysql&#8217; from the terminal whenever I want to. alias mysql=mysql5 Unfortunately shell scripts don&#8217;t seem to have access to this alias [...]]]></description>
			<content:encoded><![CDATA[<p>In another script I&#8217;ve been working on lately I wanted to call &#8216;mysql&#8217; but unfortunately on my machine it&#8217;s &#8216;mysql5&#8242; rather than &#8216;mysql&#8217;.</p>
<p>I have an alias defined in &#8216;~/.bash_profile&#8217; so I can call &#8216;mysql&#8217; from the terminal whenever I want to.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">alias mysql=mysql5</pre></div></div>

<p>Unfortunately shell scripts don&#8217;t seem to have access to this alias and the <a href="http://unix.ittoolbox.com/groups/technical-functional/shellscript-l/how-to-use-an-alias-in-shell-script-2076287">only suggestion</a> I&#8217;ve come across while googling this is to source &#8216;~/.bash_profile&#8217; inside the script.</p>
<p>Since others are going to use the script and might have &#8216;~/.bashrc&#8217; instead of &#8216;~/.bash_profile&#8217; I didn&#8217;t really want to go down that route.</p>
<p>At this stage a colleague of mine came up with the idea of creating a soft link from mysql to mysql5 inside a folder which is already added to the path.</p>
<p>We located mysql5&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&gt; which mysql5
/opt/local/bin/mysql5</pre></div></div>

<p>&#8230;and then created a soft link like so:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">cd /opt/local/bin/mysql5
ln -s mysql5 mysql</pre></div></div>

<p>And it works!</p>
<p>Of course t&#8217;is pure hackery so I&#8217;d be interested if anyone knows a better way of getting around this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2010/11/24/a-dirty-hack-to-get-around-aliases-not-working-in-a-shell-script/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Browsing around the Unix shell more easily</title>
		<link>http://www.markhneedham.com/blog/2008/10/15/browsing-around-the-unix-shell-more-easily/</link>
		<comments>http://www.markhneedham.com/blog/2008/10/15/browsing-around-the-unix-shell-more-easily/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 12:31:16 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=498</guid>
		<description><![CDATA[Following on from my post about getting the pwd to display on the bash prompt all the time I have learnt a couple of other tricks to make the shell experience more productive. Aliases are the first new concept I came across and several members of my current team and I now have these setup. [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from my post about getting the <a href="http://www.markhneedham.com/blog/2008/09/28/show-pwd-all-the-time/">pwd to display on the bash prompt all the time</a> I have learnt a couple of other tricks to make the shell experience more productive.</p>
<p><a href="http://en.wikipedia.org/wiki/Unalias#Removing_aliases_.28unalias.29">Aliases</a> are the first new concept I came across and several members of my current team and I now have these setup.</p>
<p>We are primarily using them to provide a shortcut command to get to various locations in the file system. For example I have the following &#8216;work&#8217; alias in my ~/.bash_profile file:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">alias work='cd ~/path/to/my/current/project'</pre></div></div>

<p>I can then go to the bash prompt and type &#8216;work&#8217; and it navigates straight there. You can put as many different aliases as you want in there, just don&#8217;t forget to execute the following command after adding new ones to get them reflected in the current shell:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">. ~/.bash_profile</pre></div></div>

<p>A very simple idea but one that helps save so many keystrokes for me every day.</p>
<p>Another couple of cool commands I recently discovered are <strong>pushd</strong> and <strong>popd</strong></p>
<p>They help provide a stack to store directories on, which I have found particularly useful when browsing between distant directories.</p>
<p>For example suppose I am in the directory &#8216;/Users/mneedham/Desktop/Blog/&#8217; but I want to go to &#8216;/Users/mneedham/Projects/Ruby/path/to/some/code&#8217; to take a look at some code.</p>
<p>Before changing to that directory I can execute:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">pushd .</pre></div></div>

<p>This will push the current directory (&#8216;/Users/mneedham/Desktop/Blog/&#8217;) onto the stack. Then once I&#8217;m done I just need to run:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">popd</pre></div></div>

<p>I&#8217;m back to &#8216;/Users/mneedham/Desktop/Blog/&#8217; with a lot less typing.</p>
<p>Running the following command shows a list of the directories currently on the stack:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">dirs</pre></div></div>

<p>I love navigating with the shell so if you&#8217;ve get any other useful tips please share them!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2008/10/15/browsing-around-the-unix-shell-more-easily/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Show pwd all the time</title>
		<link>http://www.markhneedham.com/blog/2008/09/28/show-pwd-all-the-time/</link>
		<comments>http://www.markhneedham.com/blog/2008/09/28/show-pwd-all-the-time/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 12:50:44 +0000</pubDate>
		<dc:creator>Mark Needham</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[pwd]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=390</guid>
		<description><![CDATA[Finally back in the world of the shell last week I was constantly typing &#8216;pwd&#8217; to work out where exactly I was in the file system until my colleague pointed out that you can adjust your settings to get this to show up automatically for you on the left hand side of the prompt. To [...]]]></description>
			<content:encoded><![CDATA[<p>Finally back in the world of the shell last week I was constantly typing &#8216;pwd&#8217; to work out where exactly I was in the file system until my colleague pointed out that you can adjust your settings to get this to show up automatically for you on the left hand side of the prompt.</p>
<p>To do this you need to create or edit your .bash_profile file by entering the following command:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">vi ~/.bash_profile</pre></div></div>

<p>Then add the following line to this file:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">export PS1='\u@\H \w\$ '</pre></div></div>

<p>You should now see something like the following on your command prompt:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">mneedham@Macintosh-5.local /users/mneedham/Erlang/playbox$</pre></div></div>

<p>Another colleague pointed out that the information on the left side is completely configurable. The following entry from the manual pages of bash (Type &#8216;man bash&#8217; then search for &#8216;PROMPTING&#8217;) show how to do this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">PROMPTING
       When executing interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input to complete a command.  Bash allows these prompt
       strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:
              \a     an ASCII bell character (07)
              \d     the date in &quot;Weekday Month Date&quot; format (e.g., &quot;Tue May 26&quot;)
              \D{format}
                     the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation.  The braces are required
              \e     an ASCII escape character (033)
              \h     the hostname up to the first `.'
              \H     the hostname
              \j     the number of jobs currently managed by the shell
              \l     the basename of the shell's terminal device name
              \n     newline
              \r     carriage return
              \s     the name of the shell, the basename of $0 (the portion following the final slash)
              \t     the current time in 24-hour HH:MM:SS format
              \T     the current time in 12-hour HH:MM:SS format
              \@     the current time in 12-hour am/pm format
              \A     the current time in 24-hour HH:MM format
              \u     the username of the current user
              \v     the version of bash (e.g., 2.00)
              \V     the release of bash, version + patchelvel (e.g., 2.00.0)
              \w     the current working directory
              \W     the basename of the current working directory
              \!     the history number of this command
              \#     the command number of this command
              \$     if the effective UID is 0, a #, otherwise a $
              \nnn   the character corresponding to the octal number nnn
              \\     a backslash
              \[     begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
              \]     end a sequence of non-printing characters</pre></div></div>

<p><a href="http://www.faqs.org/docs/abs/HTML/files.html"> This page</a> has more information on some of the other files that come in useful when shell scripting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.markhneedham.com/blog/2008/09/28/show-pwd-all-the-time/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

