<?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>Eric Wendelin&#039;s Blog &#187; Bash</title>
	<atom:link href="http://eriwen.com/category/bash/feed/" rel="self" type="application/rss+xml" />
	<link>http://eriwen.com</link>
	<description>Programming productively with open-source tools</description>
	<lastBuildDate>Thu, 26 Apr 2012 18:48:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Effective bash shorthand</title>
		<link>http://eriwen.com/bash/effective-shorthand/</link>
		<comments>http://eriwen.com/bash/effective-shorthand/#comments</comments>
		<pubDate>Fri, 29 May 2009 08:00:32 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=811</guid>
		<description><![CDATA[<img class="img-left" src="http://static.eriwen.com/images/keyboard_shell.jpg" alt=""  height="150" width="150"/>Let me tell you how to maximize your productivity on the Bourne Again SHell while minimizing your effort. <strong>bash has a ton of tricks and shortcuts</strong> that allow you to command it with little effort, and I intend to show you the features that help me day in and day out.

Today I'm going to explain the use of features like history, brace and file expansion, and other tricks by example and give you references for later. 

<h2>Master your history</h2>
Those who don't know their history are doomed to repeat it. This is arguably one of the best productivity enhancing features of any shell.

You can check your history with the <code>history</code> command, which prints your entire history by default. Alternatively, you can filter the list with:
[bash]
history 10  # prints last 10 entries
history &#124; grep cmd  # searches history for cmd
[/bash]
Each entry has a number, which you can then execute with <code>!&#60;number&#62;</code>

Now suppose I want to copy a file to a directory and then change to that directory. The quick way to do that with history is:
[bash]
cp myfile.txt my/directory/path
cd !$  # cd my/directory/path
[/bash]

or if I forget to run a command as super-user:
[bash]
vi /etc/fstab  # oops!
sudo !!  # sudo vi /etc/fstab
[/bash]
 <a href="http://eriwen.com/bash/effective-shorthand/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/tools/grep-is-a-beautiful-tool/' rel='bookmark' title='grep is a beautiful tool'>grep is a beautiful tool</a></li>
<li><a href='http://eriwen.com/productivity/aliases-and-functions/' rel='bookmark' title='Using aliases and command-line functions for speed'>Using aliases and command-line functions for speed</a></li>
<li><a href='http://eriwen.com/tools/awk-is-a-beautiful-tool/' rel='bookmark' title='awk is a beautiful tool'>awk is a beautiful tool</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="img-left" src="http://static.eriwen.com/images/keyboard_shell.jpg" alt="" height="150" width="150"/>Let me tell you how to maximize your productivity on the Bourne Again SHell while minimizing your effort. <strong>bash has a ton of tricks and shortcuts</strong> that allow you to command it with little effort, and I intend to show you the features that help me day in and day out.</p>
<p>Today I&#8217;m going to explain the use of features like history, brace and file expansion, and other tricks by example and give you references for later. </p>
<h2>Master your history</h2>
<p>Those who forget history are doomed to repeat it. This is arguably one of the best productivity enhancing features of any shell.</p>
<p>You can check your history with the <code>history</code> command, which prints your last 500 commands (or so) by default. Alternatively, you can filter the list:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# Print last 10 entries
history 10

# searches history for cmd
history | grep cmd
</pre>
<p>Each entry has a number, which you can then execute with <code>!&lt;number&gt;</code></p>
<p>Now suppose I want to copy a file to a directory and then change to that directory. The quick way to do that with history is:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
cp myfile.txt my/directory/path
cd !$  # cd my/directory/path
</pre>
<p>or if I forget to run a command as super-user:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
vi /etc/fstab  # oops!
sudo !!  # sudo vi /etc/fstab
</pre>
<p>to execute the last command starting with &quot;mount&quot;, since I don&#8217;t want to type it all out:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# Previously...
mount 192.168.0.100:/my/path/to/music /media/music

# Later...
!mount
# Repeats last mount command
</pre>
<p>Note that I <strong>often (but not always) prefer <code>Ctrl-R</code></strong>, which will search history as you type. As an added bonus you can view the command before executing it.</p>
<p>Other examples:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
eric@sawyer:~$ echo foo -a bar baz
foo -a bar baz
eric@sawyer:~$ echo !:3-4
bar baz
eric@sawyer:~$ !-2 #2nd-to-last command
foo -a bar baz
eric@sawyer:~$ ^ba^ya #replace 1st &quot;ba&quot; with &quot;ya&quot;
foo -a yar baz
eric@sawyer:~$ !^:p #MUCH cooler than &quot;echo ...&quot; ;)
foo
eric@sawyer:~$ !?bar #Last command containing &quot;bar&quot;
foo -a bar baz
eric@sawyer:~$ !:gs/ba/ya #replace all &quot;ba&quot; with &quot;ya&quot;
foo -a yar yaz
</pre>
<h3>Quick reference</h3>
<table>
<tbody>
<tr>
<td><code>!!</code></td>
<td>expands to the last command and all arguments</td>
</tr>
<tr>
<td><code>!-3</code></td>
<td>3rd-to-last command and all arguments</td>
</tr>
<tr>
<td><code>!^</code></td>
<td>first argument of the last command in history</td>
</tr>
<tr>
<td><code>!:2</code></td>
<td>2nd argument of the last command</td>
</tr>
<tr>
<td><code>!$</code></td>
<td>last argument of the last command</td>
</tr>
<tr>
<td><code>!*</code></td>
<td>all arguments of the last command, but not the command itself</td>
</tr>
<tr>
<td><code>!42</code></td>
<td>expands to the 42nd command in the history list</td>
</tr>
<tr>
<td><code>!foo</code></td>
<td>last command beginning with &quot;foo&quot;</td>
</tr>
<tr>
<td><code>!?baz</code></td>
<td>last command containing &quot;baz&quot;</td>
</tr>
<tr>
<td><code>^foo^bar</code></td>
<td>last command with the <em>first</em> occurrence of &quot;foo&quot; replaced with &quot;bar&quot;</td>
</tr>
<tr>
<td><code>!:gs/foo/bar</code></td>
<td>last command with <em>all</em> occurrences of &quot;foo&quot; replaced with &quot;bar&quot;</td>
</tr>
<tr>
<td><code>&lt;any_above&gt;:p</code>&nbsp;&nbsp;</td>
<td>prints command without executing</td>
</tr>
</tbody>
</table>
<p><a href="http://eriwen.com/downloads/history_cheatsheet.pdf">Download as PDF</a></p>
<h3>Helpful .bashrc entries for history</h3>
<p>Copy and paste these into <code>~/.bashrc</code></p>
<pre class="brush: bash; light: true; title: ~/.bashrc; notranslate">
# Don't put duplicate lines in the history
export HISTCONTROL=ignoredups

# Store a lot history entries in a file for grep-age
shopt -s histappend
export HISTFILE=~/long_history
export HISTFILESIZE=50000

# No reason not to save a bunch in history
# Takes up several more MBs of RAM now, oOOOooh
export HISTSIZE=9999

# Ignore dupe commands and other ones you don't care about
export HISTIGNORE=&quot;&amp;:[ ]*:exit&quot;
</pre>
<h3>Another neat trick with .inputrc</h3>
<p>If you are still particularly fond of the up and down arrows, copy and paste the following into a <code>~/.inputrc</code> file. This will allow you to start typing a command and then hit the up-arrow to search backwards through your history for commands starting with what you typed. I prefer other methods usually but this is pretty cool, huh?</p>
<pre class="brush: bash; title: ~/.inputrc; notranslate">
&quot;\eOA&quot;: history-search-backward
&quot;\e[A&quot;: history-search-backward
&quot;\eOB&quot;: history-search-forward
&quot;\e[B&quot;: history-search-forward
&quot;\eOC&quot;: forward-char
&quot;\e[C&quot;: forward-char
&quot;\eOD&quot;: backward-char
&quot;\e[D&quot;: backward-char
</pre>
<h3>Further reading</h3>
<p>Peteris Krumins has an excellent write-up called <a href="http://www.catonmat.net/blog/the-definitive-guide-to-bash-command-line-history">The Definitive Guide to Bash Command Line History</a> which goes in-depth on many of the above topics, should you crave more bash history goodness. </p>
<h2>Brace expansions</h2>
<p>No shorthand list would be complete without the (in)famous brace expansions. Basically, they allow you to specify part(s) of an command to repeat substituting different values of a set within braces. Let me show you what I mean:</p>
<pre class="brush: bash; title: ; notranslate">
# Quickly make a backup
cp file.txt{,.bak}
# Equivalent to 'cp file.txt file.txt.back'
</pre>
<p>This is obviously very useful to prevent having to repeat parts of files or directory paths. </p>
<p>Suppose I wanted to make a template folder structure, I could make most of the directories I need with:</p>
<pre class="brush: bash; title: ; notranslate">
mkdir -p {src,test}/com/eriwen/{data,view}
</pre>
<p>This will expand every combination so I end up with src/com/eriwen/data, src/com/eriwen/view, test/com/eriwen/data, and so forth. Being able to create a template directory structure with one line is a big time saver!</p>
<h2>Better filename expansion</h2>
<p>I'm sure you often use the * operator to match files beginning or ending with something, but bash goes far beyond that. It should be noted, though, <strong>at some point a good <code>find | grep</code> is more powerful and useful</strong>. See <a href="http://eriwen.com/productivity/find-is-a-beautiful-tool/">Find is a beautiful tool</a> for more information.</p>
<p>In addition to wildcards with <code>*</code>, you can use <code>?</code> to match any single character. You can also limit matching to certain characters with <code>[]</code>. For example:</p>
<pre class="brush: bash; title: ; notranslate">
ls
# prints &quot;myfile netbeans.conf netbeans-6.5rc2 netbeans-6.5 netbeans-6.7 src&quot;
ls netbeans-6.?
# matches &quot;netbeans-6.5 netbeans-6.7&quot;
ls netbeans-6.[1-5]*
# matches &quot;netbeans-6.5rc2 netbeans-6.5&quot;
</pre>
<h3>.bashrc entries for better filename expansion</h3>
<pre class="brush: bash; title: ; notranslate">
# Include dot (.) files in the results of expansion
shopt -s dotglob
# Case-insensitive matching for filename expansion
shopt -s nocaseglob
# Enable extended pattern matching
shopt -s extglob
</pre>
<h2>cd shorthand</h2>
<p>There are a couple quick tricks to change to oft-used directories. For example:</p>
<pre class="brush: bash; title: ; notranslate">
# Lame way to go home
cd ~

# The cool way
cd
</pre>
<p>You can also switch to the previous directory with <code>cd -</code> like so:</p>
<pre class="brush: bash; title: ; notranslate">
pwd  # prints /home/eriwen/src
cd /my/webserver/directory

# Do something...

cd -
# Now I'm back in /home/eriwen/src
</pre>
<p>To get more advanced with this, try <a href="http://eriwen.com/bash/pushd-and-popd/">mastering your directory stack with pushd and popd</a>. </p>
<h2>Conclusion</h2>
<p>Effective use of history, brace expansions, and other shortcuts will to save you a lot of time. However, <strong>nothing is more productive than no typing</strong>. <a href="http://eriwen.com/productivity/crontab-for-automation/">Automating things</a> is best where possible. If you can't automate, <a href="http://eriwen.com/productivity/aliases-and-functions/">use smart aliases</a>. </p>
<p>I know I did not cover tilde expansions, shell parameter expansions or <a href="http://beerpla.net/2008/12/22/mastering-the-linux-shell-bash-shortcuts-explained/">bash key commands</a>. You will want to check those out as well, but I find them less useful than what I've covered here. </p>
<p>Have any quick shortcuts you love? Share them in the comments!</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/tools/grep-is-a-beautiful-tool/' rel='bookmark' title='grep is a beautiful tool'>grep is a beautiful tool</a></li>
<li><a href='http://eriwen.com/productivity/aliases-and-functions/' rel='bookmark' title='Using aliases and command-line functions for speed'>Using aliases and command-line functions for speed</a></li>
<li><a href='http://eriwen.com/tools/awk-is-a-beautiful-tool/' rel='bookmark' title='awk is a beautiful tool'>awk is a beautiful tool</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/bash/effective-shorthand/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Use pushd and popd for faster CLI navigation</title>
		<link>http://eriwen.com/bash/pushd-and-popd/</link>
		<comments>http://eriwen.com/bash/pushd-and-popd/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 13:30:32 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=459</guid>
		<description><![CDATA[One of my favorite ways to save time on the command-line is to utilize the directory stack to jump between tasks. Today's article will show you how to do this and provide some tips for effective use.

<h2>What is the directory stack?</h2>
Most Linux environments have a way for you to put paths on a stack (push) and then take them off in reverse order (pop). This is useful when you have more than one directory that you need to switch between frequently. Let's take a look at how to do this.

<h2>The pushd command</h2>
Suppose you need to switch between your project: <em>~/src/myproject</em>, your web-server: <em>/opt/webserver7/logs</em> and some code examples: <em>~/examples/othercode</em> often. 

 <a href="http://eriwen.com/bash/pushd-and-popd/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/productivity/aliases-and-functions/' rel='bookmark' title='Using aliases and command-line functions for speed'>Using aliases and command-line functions for speed</a></li>
<li><a href='http://eriwen.com/bash/effective-shorthand/' rel='bookmark' title='Effective bash shorthand'>Effective bash shorthand</a></li>
<li><a href='http://eriwen.com/productivity/crontab-for-automation/' rel='bookmark' title='Start using crontab for automation'>Start using crontab for automation</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>One of my favorite ways to save time on the command-line is to utilize the directory stack to jump between tasks. Today&#8217;s article will show you how to do this and provide some tips for effective use.</p>
<h2>What is the directory stack?</h2>
<p>Most Linux environments have a way for you to put paths on a stack (push) and then take them off in reverse order (pop). This is useful when you have more than one directory that you need to switch between frequently. Let&#8217;s take a look at how to do this.</p>
<h2>The pushd command</h2>
<p>Suppose you need to switch between your project: <em>~/src/myproject</em>, your web-server: <em>/opt/webserver7/logs</em> and some code examples: <em>~/examples/othercode</em> often. </p>
<p>You add things to the directory stack with <em>pushd</em> like so:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# switch from project to web server and put on the stack
pushd /opt/webserver7/logs
# Stack is now '/opt/webserver7/logs ~/src/myproject'

# show latest errors
tail -40 errors.log
</pre>
<p>Now your in your server logs and you want to go to the examples:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# switch from project to web server and put on the stack
pushd ~/examples/othercode
# Stack is now '~/examples/othercode /opt/webserver7/logs ~/src/myproject'

# bring the 3rd directory on the stack to the front (0-based) and rotating the stack
pushd +2
# Stack is now '~/src/myproject ~/examples/othercode /opt/webserver7/logs'

# copy Java example to myproject
cp MyExample.java `dirs | awk '{print $1}'`
</pre>
<h2>The popd command</h2>
<p>Now we want to go back to my project to deploy it to our web server. Since we have our directory stack working we can do this quickly:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# go back to myproject
popd
# Stack is now '~/examples/othercode /opt/webserver7/logs'

# deploy stuff
ant dist
</pre>
<p>For the purposes of this example, let&#8217;s pretend we don&#8217;t care to go back to the examples. Let&#8217;s remove it from the stack:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# remove examples from the directory stack
popd +0
# Stack is now '/opt/webserver7/logs'
</pre>
<p>One final <em>pop</em> will get me back to my server logs once I test it out in my browser. Of course, we can keep using the stack continuously.</p>
<h2>Alternatives and nifty tips</h2>
<p>You might not always want to use the directory stack. You can use these really fast shortcuts to navigate to home or back quickly:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# change to home directory quickly in bash
cd

# change to last directory in bash
cd -
</pre>
<p>Now for some final examples that may help out just a little more:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# print directories on the stack
dirs

# hey just type less
alias p='pushd'
alias o='popd'
</pre>
<h2>Conclusion</h2>
<p>Using pushd and popd effectively can help you get around your command-line environment quickly. See the MAN pages for more information.</p>
<p>Take a bit of time to get the hang of it now and it&#8217;ll pay off later. Share your other examples or questions!</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/productivity/aliases-and-functions/' rel='bookmark' title='Using aliases and command-line functions for speed'>Using aliases and command-line functions for speed</a></li>
<li><a href='http://eriwen.com/bash/effective-shorthand/' rel='bookmark' title='Effective bash shorthand'>Effective bash shorthand</a></li>
<li><a href='http://eriwen.com/productivity/crontab-for-automation/' rel='bookmark' title='Start using crontab for automation'>Start using crontab for automation</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/bash/pushd-and-popd/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Start using crontab for automation</title>
		<link>http://eriwen.com/productivity/crontab-for-automation/</link>
		<comments>http://eriwen.com/productivity/crontab-for-automation/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 15:00:19 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=342</guid>
		<description><![CDATA[I seem to preach a lot about automation for productivity, and with good reason. You should not have to perform mundane tasks repeatedly. Crontab is a fantastic tool for simply running exactly what you want at times you specify.

Fire up your terminal or <a href="http://cygwin.com" title="Unix terminal for Windows">Cygwin</a> now. 

<h2>crontab tutorial</h2>

Suppose I want to copy my personal wiki to my website every other hour between 8:30 and 18:30 on weekdays only. This only takes a couple minutes to setup with a bit of cron-fu. 

I'm going to go ahead and use FTP to put my wiki where I want, so I wrote a quick bash script (<em>backup_wiki.sh</em>) for this purpose:
[code language="bash"]
#!/bin/bash
# File: backup_wiki.sh
HOST='mysite.com'
USER='myuser'
PASS='mypassword'

ftp -n ${HOST} <<END_SCRIPT
quote USER ${USER}
quote PASS ${PASS}
put path/to/my/wikifile.html wikifile.html
bye
END_SCRIPT
exit 0
[/code]

Sweet, so now we can just use <em>backup_wiki.sh</em>

Let's edit (or create) our new crontab file:
[code language="bash"]
crontab -e
[/code]

This brings up <em>vi</em> (by default) with a file that may have a comment or may be empty. I don't feel like using <em>vi</em> right now, so I'll change it to <em>jEdit</em> by adding the following to my .bashrc file:
[code language="bash"]
export EDITOR="[/path/to/jedit.bat (windows) or 'jedit' (*nix)]"
[/code]

Ah, that's better. Now that we can open it up in our fav. text editor, let's learn how to create an entry in our crontab file. <a href="http://eriwen.com/productivity/crontab-for-automation/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/productivity/aliases-and-functions/' rel='bookmark' title='Using aliases and command-line functions for speed'>Using aliases and command-line functions for speed</a></li>
<li><a href='http://eriwen.com/productivity/find-is-a-beautiful-tool/' rel='bookmark' title='Find is a beautiful tool'>Find is a beautiful tool</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-2/' rel='bookmark' title='Get sed savvy &#8211; part 2'>Get sed savvy &#8211; part 2</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I seem to preach a lot about automation for productivity, and with good reason. You should not have to perform mundane tasks repeatedly. Crontab is a fantastic tool for simply running exactly what you want at times you specify.</p>
<p>Fire up your terminal or <a href="http://cygwin.com" title="Unix terminal for Windows">Cygwin</a> now. </p>
<h2>crontab tutorial</h2>
<p>Suppose I want to copy my personal wiki to my website every other hour between 8:30 and 18:30 on weekdays only. This only takes a couple minutes to setup with a bit of cron-fu. </p>
<p>I&#8217;m going to go ahead and use FTP to put my wiki where I want, so I wrote a quick bash script (<em>backup_wiki.sh</em>) for this purpose:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash
# File: backup_wiki.sh
HOST='mysite.com'
USER='myuser'
PASS='mypassword'

ftp -n ${HOST} &lt;&lt;END_SCRIPT
quote USER ${USER}
quote PASS ${PASS}
put path/to/my/wikifile.html wikifile.html
bye
END_SCRIPT
exit 0
</pre>
<p>Sweet, so now we can just use <em>backup_wiki.sh</em></p>
<p>Let&#8217;s edit (or create) our new crontab file:</p>
<pre class="brush: bash; title: ; notranslate">
crontab -e
</pre>
<p>This brings up <em>vi</em> (by default) with a file that may have a comment or may be empty. I don&#8217;t feel like using <em>vi</em> right now, so I&#8217;ll change it to <em>jEdit</em> by adding the following to my .bashrc file:</p>
<pre class="brush: bash; title: ; notranslate">
export EDITOR=&quot;[/path/to/jedit.bat (windows) or 'jedit' (*nix)]&quot;
</pre>
<p>Ah, that&#8217;s better. Now that we can open it up in our fav. text editor, let&#8217;s learn how to create an entry in our crontab file.</p>
<h2>crontab file structure</h2>
<p>Lets break down a sample command that we&#8217;ll be putting into our crontab file</p>
<pre class="brush: bash; title: ; notranslate">
#min hour dom month dow command
30 8-18/2 * * 1-5 ./path/to/backup_wiki.sh
</pre>
<p>This command will run our <em>backup_wiki.sh</em> script at 8:30, 10:30, &#8230; 18:30 every Monday(1) through Friday(5). The crontab file basically has one command per line in the following format with the following separated by a space:</p>
<ul style="list-style-type: upper-roman; margin-left: 2em;">
<li>Minutes [0-59]</li>
<li>Hour [0-23]</li>
<li>Day of Month [1-31]</li>
<li>Month [1-12] &#8211; January is 1, obviously</li>
<li>Day of Week [0-6] &#8211; Sunday is 0</li>
<li>Command to run (can have spaces)</li>
</ul>
<p>An asterisk (*) means all possible values, so in our example above we mean all days of all months. You can specify a range by using a dash (-). Also, using a slash and then a number (like /2) after a command means only run on increments divisible by 2, so 8-19/2 means 8, 10, 12, 14, 16, 18. </p>
<p>Now suppose we just want to </p>
<pre class="brush: bash; title: ; notranslate">
# view our crontab entries without editing them
crontab -l

# remove your crontab file and start fresh
crontab -r

# on *some* systems (not Cygwin), view the last edit time of crontab
crontab -v
</pre>
<h2>example crontab entries</h2>
<p>You&#8217;d be surprised what you can automate. Here are some simple examples to give you ideas:</p>
<pre class="brush: bash; title: ; notranslate">
# Run backup at 3am every night
0 3 * * * ./nightly_backup.sh &gt;&gt; /logs/dir/backups.log

# Mail me feedburner subscribers every weekday
0 6 * * 1-5 mail -s &quot;Daily Subscriber Report&quot; myemail@gmail.com &lt; `get_subscribers.sh`

# Download meeting agenda wiki page every Tues/Thurs in Dec. 1st-24th
30 8 1-24 12 2,4 ./path/to/curl_get_agenda.sh
</pre>
<p>Friend Mark Sanborn has another <a href="http://www.marksanborn.net/linux/learning-cron-by-example/" title="Learning Cron by example">post about cron</a> that has other useful bits I may not have covered here. </p>
<p>I hope you found this intro. to crontab useful. Please share your ideas for automating with it in the comments!</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/productivity/aliases-and-functions/' rel='bookmark' title='Using aliases and command-line functions for speed'>Using aliases and command-line functions for speed</a></li>
<li><a href='http://eriwen.com/productivity/find-is-a-beautiful-tool/' rel='bookmark' title='Find is a beautiful tool'>Find is a beautiful tool</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-2/' rel='bookmark' title='Get sed savvy &#8211; part 2'>Get sed savvy &#8211; part 2</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/productivity/crontab-for-automation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using aliases and command-line functions for speed</title>
		<link>http://eriwen.com/productivity/aliases-and-functions/</link>
		<comments>http://eriwen.com/productivity/aliases-and-functions/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 12:00:28 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[aliases]]></category>
		<category><![CDATA[command-line]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=258</guid>
		<description><![CDATA[There are two main aspects to enhancing programming productivity, and they are what I like to call physical (decrease actual human activity) and mental (knowing the smartest way to accomplish a task) types. Humans are slow, so I want to help you prevent that slowness from killing your face-melting programming dreams.

<h2>Stop typing so much!</h2>

One great way to <strong>enhance your physical productivity is, obviously, to type less</strong>. You know what you want to do and it should take no time for you to tell your computer to do it. On the command-line, we can do this most easily with smart aliases, and perhaps creating functions that streamline our tasks for us so that we can accomplish this. 

I'm going to share with you a few techniques I use to cut the number of keystrokes I type significantly while boosting my efficiency, so break out <a href="http://www.cygwin.com" title="Cygnus + Windows">Cygwin</a> or your favorite terminal and let's get started.

<h2>Find out what commands you use most frequently</h2>

Here is a quick command you can use to figure out the 10 most used commands in your history (learned from <a href="http://lifehacker.com/software/unix/review-your-most-oftused-unix-commands-202712.php" title="Most used UNIX utilities">lifehacker's post</a>):
 <a href="http://eriwen.com/productivity/aliases-and-functions/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/groovy/crush-images-with-groovy/' rel='bookmark' title='Crush images on the command-line with Groovy'>Crush images on the command-line with Groovy</a></li>
<li><a href='http://eriwen.com/css/use-the-table-layout-css-property-to-speed-up-table-rendering/' rel='bookmark' title='Use the table-layout CSS property to speed up table rendering'>Use the table-layout CSS property to speed up table rendering</a></li>
<li><a href='http://eriwen.com/bash/effective-shorthand/' rel='bookmark' title='Effective bash shorthand'>Effective bash shorthand</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>There are two main aspects to enhancing programming productivity, and they are what I like to call physical (decrease actual human activity) and mental (knowing the smartest way to accomplish a task) types. Humans are slow, so I want to help you prevent that slowness from killing your face-melting programming dreams.</p>
<h2>Stop typing so much!</h2>
<p>One great way to <strong>enhance your physical productivity is, obviously, to type less</strong>. You know what you want to do and it should take no time for you to tell your computer to do it. On the command-line, we can do this most easily with smart aliases, and perhaps creating functions that streamline our tasks for us so that we can accomplish this. </p>
<p>I&#8217;m going to share with you a few techniques I use to cut the number of keystrokes I type significantly while boosting my efficiency, so break out <a href="http://www.cygwin.com" title="Cygnus + Windows">Cygwin</a> or your favorite terminal and let&#8217;s get started.</p>
<h2>Find out what commands you use most frequently</h2>
<p>Here is a quick command you can use to figure out the 10 most used commands in your history (learned from <a href="http://lifehacker.com/software/unix/review-your-most-oftused-unix-commands-202712.php" title="Most used UNIX utilities">lifehacker&#8217;s post</a>):</p>
<pre class="brush: bash; title: ; notranslate">
# Get most used commands from your history
history|awk '{print $2}'|awk 'BEGIN {FS=&quot;|&quot;} {print $1}'|sort|uniq -c|sort -r
</pre>
<p>My top list included <em>cd ..</em>, <em>ls</em>, <em>grep</em>, and <em>ant</em> just to name a few. Your list will differ. I probably use each at least a dozen to a hundred times per day. If we do some stupid averaging of time spent with those extra characters, we could make some completely unscientific guess that we can save about 20 minutes a day if we only had to type two or three characters (including enter) for each of these commands. </p>
<h2>Create aliases smartly</h2>
<p>Now we can take this list and create some aliases to shorten those commands most frequently used. I use <abbr title="Bourne Again SHell">bash</abbr> so I&#8217;ll edit my ~/.bashrc file (create in your home directory, if it doesn&#8217;t exist), and you can edit the file pertaining to your shell adding something like the following:</p>
<pre class="brush: bash; title: ; notranslate">
# Simple Commands
alias ..='cd ..'
alias ...='cd ../..'
alias a='ant'
alias c='cd'
alias f='find'
alias g='grep'
alias h='history'
alias l='ls -l'
alias o='popd'
alias p='pushd'

# Alias directories for quick access - links often work better but these are helpful
alias myproj='/path/to/myproject/'
alias otherproj='/other/path/directory/'

# More complex commands
alias mybox='ssh myusername@mybox.blah.com'
alias vpn='sudo vpnstuff -l connectstr &amp;&amp; sudo morevpnstuff'
</pre>
<p>You get the idea. There are obviously a lot more, but it&#8217;d get boring if I shared ALL of mine. I recommend aliasing many commands to just one character. Over time, it will become second nature and your command-line will burst in flames from your speed (I still owe Casey a new monitor&#8230; sorry buddy&#8230; forgive me?)</p>
<h2>When an alias just won&#8217;t do</h2>
<p>Now there are obviously times where you really don&#8217;t want to put it all in one command, you might not want <em>cd &#038;&#038; blah &#038;&#038; stuff || mkdir -p foo/bar</em> as an alias. Unfortunately, I see so so few people use command-line functions to their advantage, but they really help you automate tasks.</p>
<p>Suppose you want to grab a certain file off of FTP, but you&#8217;ll need to do it often as the file changes. Setup a function so you don&#8217;t have to do it physically:</p>
<pre class="brush: bash; title: ; notranslate">
# Create variables
HOST=myhostname
PASSWD=mypass
FILE=myfile.out

function getmyfile() {
  ftp -n $HOST &lt;&lt;END_SCRIPT
  user ${USER} ${PASSWD}
  cd ~/the/file/path
  get $FILE
  quit
  END_SCRIPT
}

# To invoke on the command-line:
getmyfile
</pre>
<p>You can put whatever sequence of commands you want in a function to automate your task. This can get much more complex if you like, using variables and output from other commands, <a href="http://eriwen.com/feed/">stay tuned</a>. <strong>The more you automate, the better you get at it.</strong></p>
<h2>Conclusion</h2>
<p>The point here is to <strong>express as much as you can with the least amount of effort</strong>. Keep building on your automation in this way and you&#8217;ll find yourself with much more time for more important tasks. Now go melt some faces!</p>
<p>Please share your favorite alias or function in the comments!</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/groovy/crush-images-with-groovy/' rel='bookmark' title='Crush images on the command-line with Groovy'>Crush images on the command-line with Groovy</a></li>
<li><a href='http://eriwen.com/css/use-the-table-layout-css-property-to-speed-up-table-rendering/' rel='bookmark' title='Use the table-layout CSS property to speed up table rendering'>Use the table-layout CSS property to speed up table rendering</a></li>
<li><a href='http://eriwen.com/bash/effective-shorthand/' rel='bookmark' title='Effective bash shorthand'>Effective bash shorthand</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/productivity/aliases-and-functions/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>awk is a beautiful tool</title>
		<link>http://eriwen.com/tools/awk-is-a-beautiful-tool/</link>
		<comments>http://eriwen.com/tools/awk-is-a-beautiful-tool/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 15:00:44 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=183</guid>
		<description><![CDATA[AWK is a very powerful programming language that we can use on the command-line for advanced text processing. I'd like to provide a guide so you can get started using it. I'll be covering the basics of AWK (named after Alfred <strong>A</strong>ho, Peter <strong>W</strong>einberger, and Brian <strong>K</strong>ernighan) and provide some useful examples. 

<h2>Tutorial</h2>

To best introduce <em>awk</em> I'd like to start with a practical example. Most of the applications for awk that I've dealt with involve formatting some output or data into something cleaner and more usable. This is certainly not the limit of awk, it is <strong>a full fledged language</strong> with all the power and responsibility to go with it.

Awk operates on one &#34;record&#34; at a time, which is each line by default. <strong>Each &#34;field&#34; in a record is separated by a space</strong> (by default) or another defined separator (using the -F option).
 <a href="http://eriwen.com/tools/awk-is-a-beautiful-tool/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/tools/grep-is-a-beautiful-tool/' rel='bookmark' title='grep is a beautiful tool'>grep is a beautiful tool</a></li>
<li><a href='http://eriwen.com/productivity/find-is-a-beautiful-tool/' rel='bookmark' title='Find is a beautiful tool'>Find is a beautiful tool</a></li>
<li><a href='http://eriwen.com/tools/vim-is-a-beautiful-tool/' rel='bookmark' title='Vim is a beautiful tool'>Vim is a beautiful tool</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>AWK is a very powerful programming language that we can use on the command-line for advanced text processing. I&#8217;d like to provide a guide so you can get started using it. I&#8217;ll be covering the basics of AWK (named after Alfred <strong>A</strong>ho, Peter <strong>W</strong>einberger, and Brian <strong>K</strong>ernighan) and provide some useful examples. </p>
<h2>Tutorial</h2>
<p>To best introduce <em>awk</em> I&#8217;d like to start with a practical example. Most of the applications for awk that I&#8217;ve dealt with involve formatting some output or data into something cleaner and more usable. This is certainly not the limit of awk, it is <strong>a full fledged language</strong> with all the power and responsibility to go with it.</p>
<p>Awk operates on one &#8220;record&#8221; at a time, which is each line by default. <strong>Each &#8220;field&#8221; in a record is separated by a space</strong> (by default) or another defined separator (using the -F option).</p>
<p>We&#8217;re going to print the file names, line-numbers, and function names of all duplicate functions so they&#8217;re super easy to find and remove. Suppose we have some output from grep with file names and line numbers using a command like this (pulled from my <a href="http://eriwen.com/tools/grep-is-a-beautiful-tool/">grep tutorial</a>):</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# Prints javascript functions like this - &lt;file&gt;:&lt;line-num&gt;:&lt;line-content&gt;
grep -EnH &quot;^\s*function \w+&quot; *.js | sort
</pre>
<p>That&#8217;s all good and well, but this doesn&#8217;t quite give us what we want in a clear manner, it prints all functions and information in a kinda cludgy fashion. We can clean this up with a bit of awk. First let&#8217;s learn a basic awk command:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
awk '/'^$'/ { print &quot;blank line&quot; }' myfile
</pre>
<p>This snippet will print &#8220;blank line&#8221; for line that matches the regex: ^$ (a blank line). The pattern (between the two slashes, inclusive) is optional and we&#8217;ll see in the next example:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
awk 'BEGIN { print &quot;Hello, awk!&quot; } { print $2, $1 } END { print &quot;Goodbye, awk!&quot;}' myfile
</pre>
<p>How this reads is: Before processing (BEGIN), print &quot;Hello, awk!&quot; and then <em>print</em> the second field ($2) and then the first ($1) for each line of myfile, then after processing (END) print &quot;Goodbye, awk!&quot;. The BEGIN and END clauses are optional. </p>
<p>As explained above, a field is a sequence of non-whitespace characters. So if a line contained &quot;foo bar other stuff&quot;, awk would print &quot;bar foo&quot;. </p>
<p>One more thing before continuing: awk scripts can get ugly so it is useful to know you can read a file for awk commands:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
#My awk file: foo.awk
BEGIN { print &quot;Hello, awk!&quot; }
{
    print $2, $1
    # This is an awk comment
}
END { print &quot;Goodbye, awk!&quot; }

#Invoke foo.awk
awk -f foo.awk myfile
</pre>
<p>OK, let&#8217;s add some power to that old grep command. We can use the <em>-F</em> option to specify our delimiter so let&#8217;s add to our grep command like so:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
grep -Eoni &quot;^\s*function \w+&quot; *.js | awk -F ':' '{print $3,&quot; &quot;,$1,$2}' | sort
</pre>
<p>Now we have a sorted list of function names followed by their filename and line number by spaces. We needed to print $3 first so that we could easily sort by the function name and look for duplicates, but we&#8217;re not going to do that manually&#8230; oh noooooo way. </p>
<p>Let&#8217;s make it a bit prettier and <em>uniq</em>-ify our list of functions by function:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# New part of our command
awk '{print $3,&quot;line&quot;,$4,$2}' | uniq -f 3 -D

# Full command
grep -Eoni &quot;^\s*function \w+&quot; *.js | awk -F ':' '{print $3,&quot; &quot;,$1,$2}' | sort | awk '{print $3,&quot;line&quot;,$4,$2}' | uniq -f 3 -D
</pre>
<p>Here we pipe our last command back into <em>awk</em> printing &lt;filename&gt; line &lt;line-num&gt; &lt;function-name&gt; and then use uniq on the 3rd field (-f 3) showing only the duplicates (-D). </p>
<h2>Other awk examples</h2>
<pre class="brush: bash; light: true; title: ; notranslate">
#Backup all JavaScript files with a .bak extension -- replace 'bash' with your shell
 ls *.js | awk '{print &quot;cp &quot;$0&quot; &quot;$0&quot;.bak&quot;}' | bash

#Print the number of lines that contain &quot;function&quot;
awk '/'function'/ {i = i + 1} END {print i}' myfile.js
</pre>
<h2>Conclusion</h2>
<p>AWK is admittedly a ten ton gorilla of a tool, so there is no way I could cover everything that it can do in one post. If there is enough demand I can write about some of the more advanced features like conditionals, variables, and formatting. <a href="http://eriwen.com/feed/" title="Subscribe to Eric's Blog">Stay tuned</a>!</p>
<h2>Further Reading</h2>
<p>To see how far this rabbit hole goes, you should check out a couple of my favorite references:</p>
<ul>
<li><a href="http://www.catonmat.net/blog/awk-nawk-and-gawk-cheat-sheet/">awk, nawk, and gawk cheat sheet</a></li>
<li><a href="http://en.wikipedia.org/wiki/Awk" title="AWK wikipedia entry">AWK &#8211; Wikipedia</a></li>
<li><a href="http://sparky.rice.edu/~hartigan/awk.html">Hartigan&#8217;s AWK reference</a></li>
</ul>
<p>Hope you found this informative and want to know more. I know you all probably have some awk gems to share, let&#8217;s see them!</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/tools/grep-is-a-beautiful-tool/' rel='bookmark' title='grep is a beautiful tool'>grep is a beautiful tool</a></li>
<li><a href='http://eriwen.com/productivity/find-is-a-beautiful-tool/' rel='bookmark' title='Find is a beautiful tool'>Find is a beautiful tool</a></li>
<li><a href='http://eriwen.com/tools/vim-is-a-beautiful-tool/' rel='bookmark' title='Vim is a beautiful tool'>Vim is a beautiful tool</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/tools/awk-is-a-beautiful-tool/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Get sed savvy &#8211; part 3</title>
		<link>http://eriwen.com/tools/get-sed-savvy-3/</link>
		<comments>http://eriwen.com/tools/get-sed-savvy-3/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 11:30:57 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=68</guid>
		<description><![CDATA[We will learn about the <em>sed</em> delete (d), read (r) and write (w) commands today to round out your sed toolbox. Obviously, I won't be covering everything about sed. I literally have a book on <em>sed</em> that I keep handy because there is so much to it. The major parts I am covering should help you through 99% of the cases where sed is your best option. 

Soon we'll be looking at awk and other tools to continue the quest for command-line fluency. If you haven't already, install <a href="http://cygwin.com" title="Cygnus + Windows">Cygwin</a> and check out <a href="http://eriwen.com/tools/get-sed-savvy-1/">part 1</a> and <a href="http://eriwen.com/tools/get-sed-savvy-2/">part 2</a>.

<h2>Tutorial</h2>

One of the best ways to crank out code quickly is by using templates. Using the Stream EDitor, you can streamline the use of templates.
 <a href="http://eriwen.com/tools/get-sed-savvy-3/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/tools/get-sed-savvy-2/' rel='bookmark' title='Get sed savvy &#8211; part 2'>Get sed savvy &#8211; part 2</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-1/' rel='bookmark' title='Get sed savvy &#8211; part 1'>Get sed savvy &#8211; part 1</a></li>
<li><a href='http://eriwen.com/tools/awk-is-a-beautiful-tool/' rel='bookmark' title='awk is a beautiful tool'>awk is a beautiful tool</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>We will learn about the <em>sed</em> delete (d), read (r) and write (w) commands today to round out your sed toolbox. The major parts I am covering should help you through 99% of the cases where sed is your best option. </p>
<p><img src="http://eriwen.com/images/terminal.png" style="float: right; margin: 8px 0 8px 8px" /> Soon we&#8217;ll be looking at awk and other tools to continue the quest for command-line fluency. If you haven&#8217;t already, install <a href="http://cygwin.com" title="Cygnus + Windows">Cygwin</a> and check out <a href="http://eriwen.com/tools/get-sed-savvy-1/">part 1</a> and <a href="http://eriwen.com/tools/get-sed-savvy-2/">part 2</a>.</p>
<h2>Tutorial</h2>
<p>One of the best ways to crank out code quickly is by using templates. Using the Stream EDitor, you can streamline the use of templates.</p>
<p>Suppose we have a template <abbr title="HyperText Markup Language">HTML</abbr> file that we want to reuse often. Maybe it looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;template.html&lt;/title&gt;
     &lt;/head&gt;
    &lt;body&gt;
        &lt;div id=&quot;nav&quot;&gt;Navigation here&lt;/div&gt;
        &lt;div id=&quot;content&quot;&gt;
%%CONTENT%%
        &lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Now we want to replace <em>&quot;%%CONTENT%%&quot;</em> with the contents of an HTML Fragment file. The syntax is simple: &#8216;/&lt;pattern&gt;/r&#8217;:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
sed '/^%%CONTENT%%/r fragment.htmlf' template.html
</pre>
<p>The above script will append the contents of <em>fragment.htmlf</em> <strong>immediately after</strong> <em>&quot;%%CONTENT%%&quot;</em>. So we can use the delete command to fix that:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
sed -e '/^%%CONTENT%%/r fragment.htmlf' -e '/^%%CONTENT%%/d' template.html &gt; whole.html
</pre>
<p>This might seem slightly useless, but the power here is in the simplicity. Many times I&#8217;m generating bits of Wiki code or HTML, and this has been invaluable. </p>
<p>OK, now for one more command: <em>write (w)</em>. Suppose we have a <abbr title="Comma Separated Values">CSV</abbr> file that we want to split into several files depending on the value in the last cell. We could do this with <a href="http://eriwen.com/tools/grep-is-a-beautiful-tool/" title="grep tutorial">grep</a>, or awk (coming soon), but with sed we can do it with more efficiently:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
#sedscript file
/,[0-9]+$/w numbers.csv
/,[A-Za-z]+/w letters.csv
/,[^A-Za-z0-9]+/w symbols.csv

sed -r -f sedscript original.csv
</pre>
<p>Now numbers.csv will contain all rows that the last cell containing numbers, and so on for letters.csv and symbols.csv. A neat application for this might be sorting your giant contacts list into different files based on some criteria. This is a simple example, but you can probably think of a more useful scenario where you&#8217;d want to filter and split a file. </p>
<h3>Other Examples</h3>
<pre class="brush: bash; title: ; notranslate">
#Print everything outside the &lt;html&gt; tag (check DOCTYPES)
sed '/&lt;html&gt;/,/&lt;/html&gt;/d' myfile.html

#Convert rn (DOS) to UNIX n
sed 's/$//' myfile        #Windows
sed 's/.$//' myfile       #Linux/UNIX
</pre>
<h2>Conclusion</h2>
<p>You have now learned several <em>sed</em> commands and patterns you can use to make editing files and some searching tasks much more efficient, and <strong>even better, scriptable</strong> so they can be automated in a process. One cool application would be to get comments from a set of files and post them to a wiki. It would sure make collaboration slick, right?</p>
<p>Obviously, you can bookmark this stuff but you&#8217;ll really get good at it only if you just try it out. Keep sharing your experiences and command lists, they&#8217;re great! </p>


<p>Related posts:<ol><li><a href='http://eriwen.com/tools/get-sed-savvy-2/' rel='bookmark' title='Get sed savvy &#8211; part 2'>Get sed savvy &#8211; part 2</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-1/' rel='bookmark' title='Get sed savvy &#8211; part 1'>Get sed savvy &#8211; part 1</a></li>
<li><a href='http://eriwen.com/tools/awk-is-a-beautiful-tool/' rel='bookmark' title='awk is a beautiful tool'>awk is a beautiful tool</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/tools/get-sed-savvy-3/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Get sed savvy &#8211; part 2</title>
		<link>http://eriwen.com/tools/get-sed-savvy-2/</link>
		<comments>http://eriwen.com/tools/get-sed-savvy-2/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 13:36:31 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=64</guid>
		<description><![CDATA[Now that you know a bit about the Stream EDitor from the <a href="http://eriwen.com/tools/get-sed-savvy-1/" title="SED tutorial">last sed tutorial</a>, we are going to expand our knowledge of substitution and line printing with an interesting scenario.

Suppose we want to let someone else know what kinds of functions are in a given Javascript file. Think of it as a simple sort of Javadoc for CSS or Javascript. The way we are going to do this is look at all of the files modified in the last day and then extract the comments out of them and put them somewhere (on a wiki perhaps?). <strong>Doing this kind of automation will increase team communication and productivity immensely if done correctly.</strong>

<h2>Tutorial</h2>

Download and install <a href="http://www.cygwin.com/" title="Cygnus + Windows">Cygwin</a> if you're on Windows to follow along. 

[code language="bash"]
# Single-line comments - grep is better but we can use sed
sed -n '///p' blah.js > /tmp/comments.out

# Multi-line comments
sed -n '//*/,/*//p' blah.js >> /tmp/comments.out
[/code] <a href="http://eriwen.com/tools/get-sed-savvy-2/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/tools/get-sed-savvy-3/' rel='bookmark' title='Get sed savvy &#8211; part 3'>Get sed savvy &#8211; part 3</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-1/' rel='bookmark' title='Get sed savvy &#8211; part 1'>Get sed savvy &#8211; part 1</a></li>
<li><a href='http://eriwen.com/tools/awk-is-a-beautiful-tool/' rel='bookmark' title='awk is a beautiful tool'>awk is a beautiful tool</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Now that you know a bit about the Stream EDitor from the <a href="http://eriwen.com/tools/get-sed-savvy-1/" title="SED tutorial">last sed tutorial</a>, we are going to expand our knowledge of substitution and line printing with an interesting scenario.</p>
<p>Suppose we want to let someone else know what kinds of functions are in a given Javascript file. Think of it as a simple sort of Javadoc for CSS or Javascript. The way we are going to do this is look at all of the files modified in the last day and then extract the comments out of them and put them somewhere (on a wiki perhaps?). <strong>Doing this kind of automation will increase team communication and productivity immensely if done correctly.</strong></p>
<h2>Tutorial</h2>
<p>Download and install <a href="http://www.cygwin.com/" title="Cygnus + Windows">Cygwin</a> if you&#8217;re on Windows to follow along. </p>
<pre class="brush: bash; light: true; title: ; notranslate">
# Single-line comments - grep's better but we can use sed
sed -n '///p' blah.js &gt; /tmp/comments.out

# Multi-line comments
sed -n '//*/,/*//p' blah.js &gt;&gt; /tmp/comments.out
</pre>
<p>Now, the <em>sed</em> commands above are tricky so here is how you can understand them: The <em>-n</em> option tells sed not to print anything unless you tell it specifically what to print. The comma [,] in between the two patterns tells sed to match everything between the two patterns, in this case everything between multi-line comments /* and */ and then the <strong><em>p</em>-command prints whole lines that match the pattern space</strong>.</p>
<p>We can combine these two commands to streamline a killer process.</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# sed script file
////p
//*/,/*//p

# Use the sed script to print all comments
sed -n -f sedscr blah.js &gt; /tmp/comments.out
</pre>
<p>Now we have a nice little summary of our Javascript files we can post to a wiki or diff with another version to see what was added.  Note that the <em>sed</em> print command prints the whole line, so if you have comments at the end of a line you will get the beginning of that line also. Not a perfect solution, but something quick and easy!</p>
<h2>Other Examples</h2>
<pre class="brush: bash; light: true; title: ; notranslate">
# Print lines longer than 80 characters
sed -n '/^.{81}/p' myfile

# Delete blank lines
sed '/^$/d' myfile

# Substitution optimized for speed
sed '/Yahoo/ s//Not Microhoo/g' myfile
</pre>
<h2>Conclusion</h2>
<p>You should now be getting pretty proficient with <em>sed</em>. Use it along with <a href="http://eriwen.com/productivity/find-is-a-beautiful-tool/" title="find command-line tool">find</a> and <a href="http://eriwen.com/tools/grep-is-a-beautiful-tool/" title="grep command-line tool">grep</a> and you will find yourself feeling much more comfortable on the command-line. </p>
<p><strong>I encourage you to experiment a bit and use this even in circumstances where you know it&#8217;s not necessary</strong>, just to get the hang of it. In the long run you&#8217;ll end up increasing your productivity by using these most powerful tools.</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/tools/get-sed-savvy-3/' rel='bookmark' title='Get sed savvy &#8211; part 3'>Get sed savvy &#8211; part 3</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-1/' rel='bookmark' title='Get sed savvy &#8211; part 1'>Get sed savvy &#8211; part 1</a></li>
<li><a href='http://eriwen.com/tools/awk-is-a-beautiful-tool/' rel='bookmark' title='awk is a beautiful tool'>awk is a beautiful tool</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/tools/get-sed-savvy-2/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Get sed savvy &#8211; part 1</title>
		<link>http://eriwen.com/tools/get-sed-savvy-1/</link>
		<comments>http://eriwen.com/tools/get-sed-savvy-1/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 16:02:14 +0000</pubDate>
		<dc:creator>Eric Wendelin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[sed]]></category>

		<guid isPermaLink="false">http://eriwen.com/?p=63</guid>
		<description><![CDATA[Today I'll continue the series on command-line tools for productivity, with <em>sed</em>. Stream EDitor is the most complicated tool so far, <strong>an entire language</strong> in its own right. It is much too big to cover completely in one post, so I'm going to have a few posts covering the major parts of sed. 

The bread and butter of <em>sed</em> is its search-and-replace functionality. Let's start with that and then throw in some other fun commands.

<h2>Tutorial</h2>

As with the previous posts, if you are on Windows you'll want to install <a href="http://www.cygwin.com" title="Cygnus + Windows">Cygwin</a> or one of the various other tools suggested in the previous comments. <em>sed</em> also uses regular expressions so you'll want to keep your <a href="http://www.regular-expressions.info/reference.html" title="Regular Expressions reference">regex reference</a> handy. From Wikipedia:

<blockquote>[sed] reads input files line by line (sequentially), applying the operation which has been specified via the command line (or a sed script), and then outputs the line.</blockquote>

[sourcecode language="bash"]
sed 's/#FF0000/#0000FF/g' main.css
[/sourcecode]

We can read this like so: search <strong>[s/]</strong> for red <strong>[#FF0000/]</strong> and replace it with blue <strong>[#0000FF]</strong>, globally <strong>[/g]</strong> in main.css. Two notes here: 1) This does not actually modify the file, but outputs what the file would look like if it did the replace and 2) If we left off the &#34;g&#34; at the end it would only replace the first occurrence. So let's modify the file this time. <a href="http://eriwen.com/tools/get-sed-savvy-1/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://eriwen.com/tools/get-sed-savvy-3/' rel='bookmark' title='Get sed savvy &#8211; part 3'>Get sed savvy &#8211; part 3</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-2/' rel='bookmark' title='Get sed savvy &#8211; part 2'>Get sed savvy &#8211; part 2</a></li>
<li><a href='http://eriwen.com/productivity/find-is-a-beautiful-tool/' rel='bookmark' title='Find is a beautiful tool'>Find is a beautiful tool</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ll continue the series on command-line tools for productivity, with <em>sed</em>. Stream EDitor is the most complicated tool so far, <strong>an entire language</strong> in its own right. It is much too big to cover completely in one post, so I&#8217;m going to have a few posts covering the major parts of sed. </p>
<p>The bread and butter of <em>sed</em> is its search-and-replace functionality. Let&#8217;s start with that and then throw in some other fun commands.</p>
<h2>Tutorial</h2>
<p>As with the previous posts, if you are on Windows you&#8217;ll want to install <a href="http://www.cygwin.com" title="Cygnus + Windows">Cygwin</a> or one of the various other tools suggested in the previous comments. <em>sed</em> also uses regular expressions so you&#8217;ll want to keep your <a href="http://www.regular-expressions.info/reference.html" title="Regular Expressions reference">regex reference</a> handy. From Wikipedia:</p>
<blockquote><p>[sed] reads input files line by line (sequentially), applying the operation which has been specified via the command line (or a sed script), and then outputs the line.</p></blockquote>
<pre class="brush: bash; light: true; title: ; notranslate">
sed 's/#FF0000/#0000FF/g' main.css
</pre>
<p>We can read this like so: search <strong>[s/]</strong> for red <strong>[#FF0000/]</strong> and replace it with blue <strong>[#0000FF]</strong>, globally <strong>[/g]</strong> in main.css. Two notes here: 1) This does not actually modify the file, but outputs what the file would look like if it did the replace and 2) If we left off the &quot;g&quot; at the end it would only replace the first occurrence. So let&#8217;s modify the file this time.</p>
<pre class="brush: bash; light: true; title: ; notranslate">
sed -i -r 's/#(FF0000|F00)b/#0F0/g' main.css
</pre>
<p>This is an example from the <a href="http://eriwen.com/productivity/find-is-a-beautiful-tool/" title="Find tutorial">find tutorial</a> that replaces all instances of red with green in our <abbr title="Cascading Style Sheets">CSS</abbr> file. The <em>-r</em> option here gives us extra regex functionality. As <a href="http://eriwen.com/productivity/find-is-a-beautiful-tool/#comment-822">Sheila mentioned in the find post</a>, <em>-i</em> does not work on Solaris and she suggests something like <em>perl -e s/foo/bar/g -i</em> instead.</p>
<p>Suppose we want to change a whole color scheme though, the best way is to use a sed script file like so:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
# sedscript - one command per line
s/#00CC00/#9900CC/g
s/#990099/#000000/g
s/#0000FF/#00FF00/g
...

# use sedscript with -f
sed -i -f sedscript *.css
</pre>
<p>sedscript is obviously a new file we have created. Note that we don&#8217;t quote the commands in the file. Now we have successfully changed our color scheme in our CSS files. </p>
<h2>Other Examples</h2>
<pre class="brush: bash; light: true; title: ; notranslate">
# Trim whitespace from beginning and end of line
# You *might* have to type a tab instead of t here depending on your version of sed
sed -r 's/^[ t]*//;s/[ t]*$//g'

# Delete all occurances of foo
sed 's/foo//g'
</pre>
<h2>Conclusion</h2>
<p>You should start seeing how you can make a lot of changes with simple one-liners with <em>sed</em>. Using it effectively can really increase your efficiency with some tasks. </p>
<p>Here are some good references you should bookmark (including this page of course ;)</p>
<ul>
<li><a href="http://sed.sourceforge.net/sed1line.txt" rel="nofollow">http://sed.sourceforge.net/sed1line.txt</a> &#8211; Eric Pement</li>
<li><a href="http://www.catonmat.net/blog/sed-stream-editor-cheat-sheet/" rel="nofollow">http://www.catonmat.net/blog/sed-stream-editor-cheat-sheet/</a> &#8211; Peteris Krumins</li>
</ul>
<p>I&#8217;d say that 90% of the time I use <em>sed</em> for search-and-replace, so you&#8217;ve got a good start here. As I mentioned earlier, there is a LOT more to sed. Later, I&#8217;ll show you how to make deletions, add line numbers to files, print specific lines by line number, and much more. <a href="http://feeds.feedburner.com/EricWendelin" title="Subscribe to RSS">Stay Tuned</a>, and share your favorite one-liners in the comments!</p>


<p>Related posts:<ol><li><a href='http://eriwen.com/tools/get-sed-savvy-3/' rel='bookmark' title='Get sed savvy &#8211; part 3'>Get sed savvy &#8211; part 3</a></li>
<li><a href='http://eriwen.com/tools/get-sed-savvy-2/' rel='bookmark' title='Get sed savvy &#8211; part 2'>Get sed savvy &#8211; part 2</a></li>
<li><a href='http://eriwen.com/productivity/find-is-a-beautiful-tool/' rel='bookmark' title='Find is a beautiful tool'>Find is a beautiful tool</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eriwen.com/tools/get-sed-savvy-1/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>

