Monday, July 7, 2008

Variable MultiLine Spacing With Sed On Linux Or Unix

Hey There,

Today's post is going to be on a relatively basic subject that can elude a lot of folks who use sed casually. I, myself, for years, only used it to print out matched patterns or do pattern substitutions, but it's capable of much more than that. I don't think it's quite up there with awk (insofar as the programming functionality goes), but it does have lots of neat features (like letting you switch between the current and hold buffer, for example) that can sometimes make it the preferred tool for the job. Especially if you're like me and you're not attached to any one language or interpreter. My basic philosophy is: Whatever can get it done the fastest and most efficiently. I think it works nicely, as philosophies go, since I also compulsively automate everything ;)

For this post, we'll focus on "line spacing" (If anyone calls it something else, I'm referring to the number of spaces between lines). This is one thing that sed can do relatively simply and which is requested quite often from end users. The following tips should work for both Unix and Gnu/Linux sed.

The great thing about this feature is that it's so easy to use that, if you haven't used it already, you'll be amazed at the simplicity :)

Say, for instance, you had a file named FILE with the contents:

abcdef
ghijkl


this is all you would have to do with sed to make it double-spaced (Note that I'm leaving the output redirection to another file, since it's not really germane to the explanation and you probably already know how to redirect the output of one process to another. And, since this blog is for users of all skill levels, check out any of these old posts on using sed in a wide variety of situations if you don't. See below for more information on this feature:

host # sed G FILE
abcdef

ghijkl

# host


Pretty simple, yeah? :) The "G" argument to sed simply appends whatever follows it to the pattern space that gets printed out. Since we didn't have anything to print out, it prints a space by default.

Now, if you want to triple space, it's just a little more complicated, but not much. Here's how you'd do that

host # sed 'G;G' FILE
abcdef


ghijkl


#host


Note that we had to put the arguments in single quotes, since there are (of course) more than one ;) We could have written the last command as:

host # sed 'G' FILE

and gotten the same result as without the quotes, since there was only one argument to sed. If you want to quadruple-space, just use 3 G's, etc. That's about as simple as it gets on a single command line without control characters :)

It's also interesting to note (and overlooked in this old post on using Perl like sed) that you can use "r" and "w" to read from, and write to, files so you don't need to do any redirection outside of your one-liner.

For instance, if you wanted to read information in from another file (FILE2 with contents "xyz") and double space, you could type:

host # sed 'G;r FILE2' <FILE
abcdef

xyz
ghijkl

xyz
host #


Not exactly the same, but pretty useful in different situations.

Also, you can write out to a file, using w, so you don't have to do output redirection after-the-fact, like this (we'll overwrite the FILE2 file with the contents of FILE):

host # sed 'G;w FILE2' <FILE
abcdef

ghijkl

host # cat FILE2
abcdef

ghijkl

host #


Hope you enjoyed today's post and it gets you a little more interested in sed. We'll be looking at in the future, of course, as there are a lot more things you can do with it (especially if you escape the command-line construct)

Cheers,


, Mike