An introduction to sedThis qref is written for a semi-knowledgable UNIX user who has just come up against a problem and has been advised to use sed to solve it. Perhaps one of the examples can be quickly modified for immediate use.
For More InfoA good reference for sed is the O'Reilly handbook for sed and awk. There should be a copy available in the CS Department library. Further references are the UNIX in a Nutshell and UNIX Power Tools books, also in the CS Department library.
Introduction
Some basics:In all probability, the command you need most is the "s" command. It Substitutes one thing for another. The simplest way to do this is like the above examples:>sed 's/color/colour/g' filename The "g" at the end stands for "global". What it really means, though, is to replace every occurence on the line. If you leave it off, only the first occurence on each line will be changed. You will encounter problems if you attempt to use the following characters in the string to replace: .*[]^$\These characters mean special things. If you mean to replace literal occurences of those characters, preface them with a backslash. So, don't do >sed 's/[J.S. Bach {$ for music}]/[Bach, J.S {$ for music}]/' filename Instead, do >sed 's/\[J\.S\. Bach {\$ for music}\]/[Bach, J.S {$ for music}]/' filename Note that this does not apply to the replacement string. What if you want to perform more than one such replacement at a time? You would try something like this: >sed 's/color/colour/g' 's/flavor/flavour/g' filename but it wouldn't work. sed would look for a file named "g" in the directory "s/flavor/flavour". The "-e" flag to sed makes it realize that the next option is a part of the script, instead of a filename. You also must use it for the first part of the script, when you have more than one part. So, you would use >sed -e 's/color/colour/g' -e 's/flavor/flavour/g' filename If you only had one replacement to do, you could still use the "-e" flag, but you don't need to. The various commands are applied in the order given to sed, so if you ran >sed -e 's/color/colour/g' -e 's/colour/color/g' filename it would turn "color" to "colour" and then back to "color". So, all occurences of "color" or "colour" would end up as "color". This is an inefficient way to do that, though. What if you want to replace something that contains a '/' character? This is a common problem with filenames. You could escape each one, like so: >sed 's/\/usr\/bin/\/bin/g' filename This is not fun for long pathnames. There is a nice alternative: sed will treat the character immediately after the 's' as the separator, so you could do something like >sed 's#/usr/bin#/bin#g' filename Using regular expressionssed can use regular expressions just like ed(1) can. Here are some common uses of regular expressions.
Substitution and SavingUp to this point, we have concentrated on deleting things that we match with "[]" and '.'. That's because we had no way of saving what we matched. The "\(" and "\)" operators will save whatever is found between them. Notice that these parentheses must be preceded by a backslash, while the characters ^$[].*\ don't need a backslash to act in a non-literal fashion. The first pair of "\(\)" saves into a place called "\1", and the second pair into "\2", and so on.>sed 's/^\([A-Z][A-Za-z]*\), \([A-Z][A-Za-z]*\)/\2 \1/' filename will turn "Lastname, Firstname" into "Firstname Lastname". Notice how the comma is placed outside the first pair of "\(\)" so it doesn't get inclued in the last name. Otherwise, the result would be "Firstname Lastname,". Sometimes you will want to apply a substitution only to lines that meet some criteria that you can't specify in the string to be replaced. You do this using something called an "address". It comes before the "s" command. You can limit the command to a range of lines: >sed '1,20s/foobar/fubar/g' filename The line count is cumulative across files, and starts at 1. You might want to apply a change only to lines that contain a string: >sed '/^Aug/s/Mon /Monday /g' filename Or to lines that don't contain a string:
>sed '/^Aug/,/^Oct/s/Mon /Monday /g' filename Normally sed reads a line, processes it, and prints it out. If you only want to see the lines that your command acted upon, then you don't want it to print out everyting. The "-n" flag will stop sed from printing after processing. So, >sed -n 's/fubar/foobar/g' filename will print nothing at all. You must use the 'p' flag to the 's' command to make it print out what it has processed: >sed -n 's/fubar/foobar/gp' filename
Sed from a fileIf your sed script is getting long, you can put it into a file, like so:# This file is named "sample.sed" # comments can only appear in a block at the beginning s/color/colour/g s/flavor/flavour/g s/theater/theatre/gThen call sed with the "-f" flag: >sed -f sample.sed filename Or, you can make an executable sed script: #!/usr/bin/sed -f # This file is named "sample2.sed" s/color/colour/g s/flavor/flavour/g s/theater/theatre/gthen give it execute permissions: >chmod u+x sample2.sed and then call it like so: >./sample2.sed filename This documentation was originally written by Andrew M. Ross. Copyright (c) HMC Computer Science Department.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with the no Invariant Sections, with no
Front-Cover Texts, and with no the Back-Cover Texts.
A copy of the license is included in the section entitled ``GNU Free Documentation License.''
HMC Computer Science Department Olin Science Center 301 E. Twelfth Street Claremont, CA 91711-5980 USA PH : (909) 621-8225 FX : (909) 621-8465 Info Email: CS Staff or Admission Office |