TweetFollow Us on Twitter

What's Rattling Around in my sed

Volume Number: 21 (2005)
Issue Number: 12
Column Tag: Programming

Mac In The Shell

What's Rattling Around in my sed

by Edward Marczak

Automating edits.

OS X is Unix" - a statement that has been under a bit of debate since the OS shipped. It does look like a duck and does smell like a duck, but it doesn't really quack like a duck. While many, many projects will, unmodified, compile and run under OS X, there are enough that do not thanks to the acrobatics that OS X engages in underneath it all. That's why we all have to delight in any project that comes pre-installed for us - no compile necessary, and we know it'll be on all OS X boxes that we touch - and runs identically to the Solaris/IRIX/Linux/HP versions. There are two indispensable utilities that fall into this category: sed and awk. These will consume us the next few columns. With sed ("the stream editor") being the more simple of the two, that's where we'll start.

Cuckoo for Cocoa Puffs!

OK - it's not that kind of cereal! sed is a "serial editor" as in it will repeatedly make changes to an input stream in series. I was, not all that long ago, amongst a group of like-minded Mac techs and one person asked how he could take a single file and alter it many times over for specific destinations. I immediately offered sed as a solution. "What?" "sed," I repeated. Blank stares. sed and awk are too useful to not use!

sed takes input, via file name or standard input, processes the file and pumps the results back via standard out. However, instead of making edits interactively, like you might with vi or a word processor, sed allows you to script your edits, almost as if you're creating a macro. This script can then be applied to many (or, any) files. Just like your editor has commands that will insert a line, delete a line and so on, so does sed. Even more impressive, is sed's ability to alter a file, or stream through substitution and regular expressions. And there's the rub. We can 't talk about sed without talking about regular expressions (RE).

Lucky Charms

Regular expressions are fundamental to the Unix landscape. Understanding them makes your computing life better and easier on many levels. Even many GUI editors have support for RE built in. Notable examples are BBEdit and Dreamweaver. There are patterns that you can describe with RE that just can't be done cleanly otherwise. A full discourse on regular expressions is its own article or even book. Fortunately, there's plenty of material out there. The February 2005 issue of MacTech ran, "Matchmaking With Regular Expressions" by Paul Ammann, so if you've been a subscriber, or have that issue, you should start there. O'Reilly has an entire book on RE alone called "Mastering Regular Expressions." If you've already mastered RE, please skip ahead to the next section. Otherwise, I'm ready to present the world's shortest intro and tutorial on regular expressions.

Regular expressions are one of those things that can be a little daunting at first, because the syntax is a little out of the ordinary. However once you dive in, you'll start seeing patterns everywhere that are a great fit. I will admit that I'm going to gloss over some of the finer details regarding RE.

A regular expression is just that: an expression. It's not to be taken literally as it is by itself. This is because most patterns involve metacharacters. We all intrinsically now understand the wildcard metacharacter, "*". If we were to type into our shell, "ls -l *", we'd expect a listing of all files, as we're not literally looking for a file named "*". Similarly, sed is heavily dependant on metacharacters in RE. Also, as an expression, it is something that the interpreter evaluates, much like a mathematical expression. Since understanding how the interpreter evaluates each metacharacter is fundamental to your understanding of the concepts covered in this piece, that's where we'll start.

Non-metacharacters are matched verbatim. If you ask sed (or grep) to match "Cat", it will match a capital "C" immediately followed by a lower case "a", adjacent to a "t". No other permutation will match. Each character is its own RE that matches that single character. To match any single character, use the "." (dot) meta. So, a regexp of "ca." would match "cat" or "cab", but not "rat". To match a wider swath of "any" characters, use the wildcard "*" (asterisk). The asterisk behaves a little differently than you may think. It modifies the previous character, and matches zero or more characters. Again: it modifies the previous character. If you are looking for "car", a RE of "c*r" will not do what you expect. Yes, it will match "car", but will also match any word with "r" in it. Huh? "c*r" says, "match zero or more of the letter c, and then an r." That re-enforces the second point: it will match zero or more characters. To find words that begin with "c" and end with "r", you can use "c.*r", which will match "cr" (if that was a word), "car" and "cur", but also "choir", "czar", "carpetmonger", "calcaneoplantar"...and much more, as we'll see. This says, "match the letter 'c', zero or more of any character, and then an 'r'".

Well, if you actually ran the above on a dictionary file, you'd notice that you'd get a lot more that expected. How does "c.*r" match "buckaroo"? We need to learn two more metacharacters: beginning-of-line "^" (circumflex) and end-of-line "$" (dollar sign). So, to truly get words that begin with "c" and end with "r", you'd use a RE of "^c.*r$". That says, "at the beginning of the line, look for a 'c', then match zero or more characters, and finally match an 'r' at the end of the line."

Cheerios

Let's jump right in with an example, shall we? Probably the sed command (or, mnemonic) used most often is substitute - "s":

sed -e 's/Mike/Michael/' letter.txt

This tells sed to run through the file letter.txt and replace 'Mike' with 'Michael'. Note the use of the forward slash as a delimiter. However, if you read the preceding section, you may have come to expect that it's never quite that simple. The substitute command will only make the substitution for the first occurrence on a line, unless you add the global flag - 'g'. Simply, the command should be:

sed -e 's/Mike/Michael/g' letter.txt

That'll get all of them. You can even make multiple changes in a file:

sed -e 's/Dot/Dorothy/g' -e 's/Chris/Christopher/g' personnel.txt

This gives us an opportunity to talk about how sed applies edits, which is critical to understanding what's going on.

sed works with a line that it brings into its pattern space. It then applies all edits that you've asked for to this line, moves the updated line to stdout (if appropriate), and then brings the next line into the pattern space. To really understand this, a demonstration is in order. The following text is in a file called 'short_story.txt':

    Bill and Michael went to the store. Bill needed to buy some butter, eggs and flour. He and Michael were in a hurry to bake a cake for their parent's Anniversary. Once they got home, Bill and Michael realized that they forgot cake icing.

Of course, Michael, being the older brother, feels he should precede Bill in the story. Well, you have sed and that's an easy task, right? Wherever you see 'Michael', change it to 'Bill', and wherever you see 'Bill', change it to 'Michael':

$ sed -e 's/Bill/Michael/g' -e 's/Michael/Bill/g' short_story.txt 

But when you run the command, you get this output:

    Bill and Bill went to the store. Bill needed to buy some butter, eggs and flour. He and Bill were in a hurry to bake a cake for their parent's Anniversary. Once they got home, Bill and Bill realized that they forgot cake icing.

What happened? Let's trace:

    1. sed brought the first line into pattern space.

    2. sed found the pattern 'Bill' and substituted 'Michael', making the line:

    "Michael and Michael went to the store. Michael needed to buy"

    3. sed then applied the second edit we asked for, making 'Michael' into 'Bill', resulting in the output we just saw.

Be aware of that interaction. Later on (read: next month's column), I'll show how to deal with that. Using the simple substitution above is great static files, like a checklist:

Hello -=firstname=-!  Welcome to Acme and Associates.  There are some things 
   you'll need to know to get started with our network.  Please keep a record of these items:
Name: -=username=-
Phone: -=phonenum=-
IP address: -=ipaddr=-
Thanks!

You could write a sed script that alters this file appropriately before mailing it out. Of course, substitution gets much more interesting when combined with regular expressions. But first, we need to look at some of the other sed commands.

Rice Krispies

As mentioned, sed is an editor. What good would an editor be if it couldn't add and delete lines? The simpler of the two is delete. Delete erases the entire pattern space, and then continues on to the next line - there's nothing left to match after that.

sed -e '1d' short_story.txt

This prints out our short story, minus the first line - that gets deleted. Of course, delete is even more powerful when combined with regular expressions. How about one that gets rid of bash comments:

sed -e '/^#/d' bashscript.sh

To create more complex sed interactions, we can put all of our commands in a file to make a sed script. By placing your edits into a sed script, you gain the advantage of making your routine reusable, and being able to build it up slowly - these scripts can get complex very quickly, and it's not often that you get it 100% right on the first shot. If you were to save the following into a file named "editscript.sed":

1d
s/Bill/William/g
s/cake/pie/g

...you'd be able to run it against our short story, using the "-f" flag, and see each edit:

$ sed -f editscript.sed short_story.txt 
some butter, eggs and flour.  He and Michael were in a hurry
to bake a pie for their parent's Anniversary.  Once they got
home, William and Michael realized that they forgot pie icing.

First line deleted, "Bill" becomes "William" and "cake" becomes "pie". Using a sed script also brings some other advantages in terms of opening up other commands for our use. First and foremost, as opposed to delete, we can insert. Insert is one of the odd sed commands in that it expects its input to be broken up over more than one line. If we wanted to insert a title at the top of our story, we could use this:

1i\
The Wedding Cake

With insert, you must include a backslash after the command with the text to be inserted on the next line.

Also, within a sed script, we can use functions. Functions in sed? Well, perhaps they're not like traditional functions, but we can opt for a series of edits to take place on a sub-set of the document we're editing:

/^    Bill/ {
        s/Bill/William/
        s/    / /
}

(note here that the second edit is "s slash space space space space slash tab slash". Thank you for your patience.)

This tells sed, "only on lines that start with four spaces immediately followed by 'Bill' will you make the following edits: change Bill to William and then change four spaces to a tab character." Think of all the conditional ways you can program edits with this feature! (OK, did I get too excited over that?)

Again, the power of regular expressions increases sed's value exponentially. This is especially effective when dealing with any kind of mark-up. And to make this even more powerful, we need to introduce addressing. So far, our commands have not had an address, which makes sed apply edits to each line. Another possibility is to supply one address. This can come in the form of a number, or a pattern. If we only wanted to make substitutions on lines that end with a period, we could use something like this:

sed -e '/\.$/s/\./!/g' short_story.txt

(The address to affect is in bold)

This tells sed, "only on lines that end with a period ("\." - we have to escape the period, otherwise it'll match any single character), substitute an exclamation point for any period on the line." OK, it's a completely contrived example, but it should convey the power this brings. I used a not so contrived example the day I finished this article. I was working on a mailing for a client (not a spammer), that needed to retrieve their client e-mail addresses from a Crystal Reports CSV file. CR writes crummy CSV, only enclosing fields in quotes if they have an embedded comma. While that's valid, the software this client was using for mailing didn't like that format too much. sed to the rescue! Here's what I did:

$ sed '/^\"/s/,/ /1' clients.csv > clients2.csv

This told sed, "only on lines that begin with a quote (gotta escape the quote there), substitute a space for the first comma that you find." This output was then redirected to another file, which we had the mailing software (happily) read in.

Don't feel confuSED

Just learning the sed presented in this month's column will bring you incredible power on the command line and when editing files in batch or under the command of a shell script. Believe it or not, there's more! If this was your first exposure to sed, practice, practice, practice! Get a test file (or two or three) and see what sed does when you issue various commands. Next month, I'll cover a little more on the quirky interactions, other commands and more advanced usage.

While I normally say, 'see you next month,' and I mean 'in print,' I really do hope to see everyone next month in person: at MacWorld! I'll be there all week, and presenting the, "From the Chime to the Desktop" session on Wednesday in the IT track conference. Please say hello if you'll be in San Francisco! Of course, I'll still see everyone in print. Until then, let sed rip through some files for you!


Ed Marczak owns and operates Radiotope, a technology consulting company. Ed will be speaking and hanging out at MacWorld SF 2006 all week - hope to see you there! He also deposits tech thoughts on-line at http://www.radiotope.com

 
AAPL
$562.29
Apple Inc.
-3.03
MSFT
$29.06
Microsoft Corpora
-0.01
GOOG
$591.53
Google Inc.
-12.13
MacTech Search:
Community Search:

Men in Black 3 Review
Men in Black 3 Review By Rob Rich on May 25th, 2012 Our Rating: :: WE'LL TAKE IT FROM HEREUniversal App - Designed for iPhone and iPad Gameloft delivers a surprisingly awesome free-to-play management game based on a beloved series... | Read more »
SketchBook Ink Review
SketchBook Ink Review By Lisa Caplan on May 25th, 2012 Our Rating: :: SIMPLEiPad Only App - Designed for the iPad SketchBook Ink has a welcoming interface but lacks key features   Developer: Autodesk Inc. | Read more »
Autumn Dynasty Review
Autumn Dynasty Review By Kevin Stout on May 25th, 2012 Our Rating: :: NEARLY FLAWLESSiPad Only App - Designed for the iPad Autumn Dynasty is an oriental-themed real-time strategy game.   | Read more »
Our Annual “Holy Cow It’s Memorial Day A...
So, it’s that time of year again! BBQs, lawn chairs, beer, and the ability to finally wear shorts with sandals without fear of frostbite. Tan those legs and check out all the huge sales that are going on across the App Store below. We’ll try and... | Read more »
FREEday 5/25/12 – “They Call Me FREE but...
Another week of freebies, this time with very little in the way of “Big Name” titles. No need to panic, it’s intentional. Anyone browsing the App Store will no doubt see the more popular games anyway. | Read more »
Shoot the Zombirds Review
Shoot the Zombirds Review By Kevin Stout on May 25th, 2012 Our Rating: :: ADDICTINGUniversal App - Designed for iPhone and iPad Shoot the Zombirds is an archery game where the player shoots arrows at avian zombies.   | Read more »
Apple Debuts Free App of the Week Promot...
Apple has made a couple of changes to their weekly app features that pop up in the Featured tab of the App Store. While “App of the Week” and “Game of the Week” appear to be just rebranded as “Editors’ Choice,” there’s a new feature: the Free Game... | Read more »

Price Scanner via MacPrices.net

Apple Maintains Leading Mobile Device Manufacturer...
Milennial Media says Apple continued to be the number one mobile device manufacturer on their platform in Q1, representing 28% of the top manufacturers impression share. Apple iPhone accounted for 15... Read more
Asustek To Launch Three New ZenBook Ultrabook Mode...
Digitimes’ Rebecca Kuo and Steve Shen report that PC-maker Asustek Computer will launch three new models to its ZenBook Prime Ultrabook lineup – the UX21A, UX31A and UX32VD – in June, featuring full... Read more
Yahoo! Introduces Axis Search Browser For Mobile D...
Yahoo! has announced the availability of Yahoo! Axis, a new Web browser tool that it claims will re-imagine how people search and browse on the web, Axis offering a faster, smarter search with... Read more
Android- and iOS-Powered Smartphones Expand Market...
Smartphones powered by Android and iOS mobile operating systems accounted for more than eight out of ten smartphones shipped in the first quarter of 2012 (1Q12), according to the International Data... Read more
Roundup of Memorial Day Weekend MacBook Pro sales,...
 Apple resellers have MacBook Pros on sale for up to $240 off MSRP this Holiday weekend. Here is a roundup of the best prices available from any reseller: (1) B&H Photo has MacBook Pros on sale... Read more
iPad wait times down to 1-3 days at The Apple Stor...
The Apple Store Online is now reporting a 1-3 business day wait on all iPad orders, as it appears that Apple is clearing out their backlog. The iPad is available in Wi-Fi or Wi-Fi + Cellular... Read more
Roundup of Memorial Day Weekend MacBook Air sales,...
 Apple resellers have MacBook Airs on sale for up to $101 off MSRP this Holiday weekend. Here is a roundup of the best prices available from any reseller: (1) B&H Photo has 11-inch and 13-inch... Read more
13″ 2.8GHz MacBook Pro on sale for $100 off MSRP
Adorama has lowered their price on the 13″ 2.8GHz MacBook Pro to $1399 including free shipping plus NY/NJ sales tax only. Their price is $100 off MSRP, and it’s the lowest price for this model from... Read more

Jobs Board

*Apple* Solutions Consultant-Retail Sal...
The Apple Solutions Consultant is an Apple employee who oversees the sales, merchandising, and operations of an Apple Store-in-a-Store in a single unit retail Read more
iPad/iPhone Developer at Recruitarrow (P...
Job Responsibilities and Requirements: These solutions must be aligned with business and IT strategies and comply with the organization's architectural standards. Involved in the full systems life... Read more
Mobile iphone App with API Connections t...
See requirements. Develop mobile app that interfaces to access database on webserver and infusionsoft through API. Desired Skills: iPhone, Mobile, Infusionsoft, API Read more
*Apple* Retail - Manager - Natick Colle...
Much more than just a place for amazing products, the Apple Retail Store serves a dazzling range of needs for its customers. Not only can users get hands-on experience Read more
XML image iPhone App at Elance.com (Uppe...
I want a similar iphone app like the following App below: /us/app/hd-tattoo-designs-catalog/id524766650?mt=8 I want a ... can tell who knows the expertise and who outsources the project to others.... Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.