sed¶
Stream Editor¶
sed is a utility that allows us to edit a stream of data by replacing some existing text with the desired one.
Version¶
sed -Vprints thesedversionsed -hprints a summary of thesedcommand
Basic command¶
- Basic sed command to substitute characters is
sed 's|pattern to match|pattern to replace the matched pattern|' - a more common form is to use
/instead of|:sed 's/pattern to match/pattern to replace the matched pattern/' - there are always three
/or|, or any other delimiter like:; but there should always be three otherwise an error is raised - it is common to use a delimiter that is not a character in the input string being processed
- for instance,
echo day | sed 's|day|night|'producesnight sedworks on every line, one by one and acts on the first match (greedy)
Regular Expressions¶
- regular expressions work perfectly fine for the pattern to match (however,
\ddoes not work, use[0-9]instead)echo "abc 123 abc 456" | sed 's/[0-9][0-9]*/& &/'outputsabc 123 123 abc 456echo "abc 123 abc 456" | sed 's/[0-9]*/& &/'outputsabc 123 abc 456because[0-9]*matches 0 or more characters and the start of line is a match;[0-9][0-9]*matches a string only made up of digits
- to use
+character in the regular expression search, use-rflag to signify extended regular expressionsecho "abc 123 abc 456" | sed -r 's:[0-9]+:& &:'outputsabc 123 123 abc 456- in the extended regex setup, we dont need to escape capturing brackets with a
\
- For single matches,
&can be used to refer to the matched patternecho "123 abc" | sed 's/[0-9]*/& &/'gives123 123 abc
- Like regular expressions, we can
\1upto\9(9 captured groups) to refer back to any matched groupecho ab1e | sed -r 's/([a-z]+)/\1\1/'outputsabab1e
- the captured group can be referred to in the search expression as well, say to check duplicated words
echo ab abe | sed -r 's/([a-z]+) \1/dup/'outputsdupeecho ab ae | sed -r 's/([a-z]+) \1/dup/'outputsab ae
Flags and Options¶
-r- extended regular expressions; described in the previous section
g- to change all the occurrences of a word on the line, use the
gflagsed s/pattern/replacement/g echo ab1e | sed -r 's/([a-z]+)/9/g'outputs919
- to change all the occurrences of a word on the line, use the
I- performs case insensitive matching
echo abcABCaBc | sed 's/abc/1/gI'outputs111
-n- is no printing, with just
-nnothing will be printed
- is no printing, with just
p- specifically asks
sedto print the modified lines - if no match is found, the lines are printed as is
- for any line, if a match is found, the line is printed twice
-ntogether withpwill print only the lines where a match is foundprintf "abc\nABC" | sed -n 's/abc/1/p'outputs1printf "abc\nABC" | sed 's/abc/1/p'outputs1\n1
- specifically asks
-e- allows executing multiple
sedcommands sequentially printf "Ah! How do you do good sir this fine evening?" | sed -e 's/e/E/g' -e 's/o/O/g' -e 's/E/e/'outputsAh! HOw dO yOu dO gOOd sir this fine EvEning?- note how the last executed command changes the first
Eback toe - one can also put different commands on separate lines using
\like in a shell script
- allows executing multiple
Ranges and Specifying Lines¶
- Restrict to a line number
- Add the line number before the command to act only on that line
sed 'num s/pattern/replace/printf "abc\nABC\naBc" | sed '2 s/abc/replace/I'
- Ranges by line number
- Use two comma separated numbers instead of a single number like above to define a range for making substituitions
- only substitute in first 10 lines,
sed '1,10 s/pat/rep/' - only substitute in lines 10 to 20,
sed '10,20 s/pat/rep/' - only substitute in lines 20 to end,
sed '10,$ s/pat/rep/' $denotes the end, similar to other utilities in shell- in case multiple files are being processed, the line numbers are assumed to be cumulative
Addresses¶
sed has the ability to only apply the commands to lines that match a specific pattern using the sed /pattern/ command syntax.
* sed -n '/abc/ p mimics grep; the command we are asking sed to execute is p
* there should always be a command to execute, otherwise an error is raised
Specific Use Cases¶
- a use case of
sedis to print the columns header of a file on different linesecho 'colA|colB|colC|colD' | sed -e 's/|/\n/g' | cat -nwhere|was the column delimitercat -nprints the contents and the line numbers as well
- Another useful usecase is to print specific lines of a file
- `sed '20,25p' filename
- This will print lines 20-25 of
filename