Table of contents
- Write the result to another file
- Replace first occurrence on every line
- Replace values of all occurrences
- Replace value of first occurrence in the file
- Replace all occurrences on n-th line
- Replace all occurrences within a range of lines
- Replace all occurrences on every line matching pattern
- Replace all occurrences on every line NOT matching pattern
- Replace first occurrence after a pattern
- Delete lines matching pattern
- Delete n-th line
- Insert before line
- Insert after line
- Use other delimiter
Write the result to another file
Content of file_1
(before command is executed)
Hello World
Command
sed 's/Hello/Goodbye/;w file_2' file_1
Content of file_1
(after command is executed)
Hello World
Content of file_2
(after command is executed)
Goodbye World
Replace first occurrence on every
Input file
aa bb bb aa bb
Command
sed 's/bb/dd/' file
Output
aa dd bb aa dd
Replace values of all occurrences
Input file
aa bb bb aa bb
Command
sed 's/bb/dd/g' file
Output
aa dd dd cc dd
Replace value of first occurrence in the file
Input file
aa bb bb aa bb
Command
It only works on GNU sed.
See also: https://www.gnu.org/software/sed/manual/html_node/Range-Addresses.html
sed '0,/bb/{s/bb/dd/}' file
Output
aa dd bb cc bb
Replace all occurrences on n-th line
Input file
aa bb bb aa bb
Command
# replace all occurrences on 2nd line sed '2s/bb/dd/g' file
Output
aa dd dd aa bb
Replace all occurrences within a range of lines
Input file
aa1 aa2 aa3 aa4 aa5
Command
# replace occurrences from 2nd line to 4th line sed '2,4s/aa/dd/g' file
Output
aa1 dd2 dd3 dd4 aa5
Replace all occurrences on every line matching pattern
Input file
a 1 a 2 a 1 x b 1 b 2 b 1 x c 1 c 2 c 1 x
Command
# replace "1" with "10" on all the lines containing "b" sed '/b/s/1/10/g' file1
Output
a 1 a 2 a 1 x b 10 b 2 b 10 x c 1 c 2 c 1 x
Replace all occurrences on every line NOT matching pattern
Input file
a 1 a 2 a 1 x b 1 b 2 b 1 x c 1 c 2 c 1 x
Command
# replace "1" with "10" on all the lines NOT containing "b" sed '/b/!s/1/10/g' file
Output
a 10 a 2 a 10 x b 1 b 2 b 1 x c 10 c 2 c 10 x
Replace first occurrence after a pattern
Input file
server-alpha: host: '192.168.0.1' port: 9090 server-beta: host: '192.168.0.1' port: 9091 server-charlie: host: '192.168.0.1' port: 9092
Problem
Change the host of server-beta
to 192.168.0.2
. Values of other hosts remain unchanged.
Command
sed -e '/server-beta/! b' \ -e ':label1' \ -e 's/192.168.0.1/192.168.0.2/' \ -e 't label2' \ -e 'n' \ -e 'b label1' \ -e ':label2' \ -e 'n' \ -e 'b label2' \ file
Output
server-alpha: host: '192.168.0.1' port: 9090 server-beta: host: '192.168.0.2' port: 9091 server-charlie: host: '192.168.0.1' port: 9092
Explanation
It uses the sed branching commands b
and t
.
/server-beta/! b
- if pattern space doesn't containserver-beta
, it will jump to the end of script.:label1
- declare a label with namelabel1
s/192.168.0.1/192.168.0.2/
- Replace192.168.0.1
with192.168.0.2
t label2
- if the previous replacement is done, jump tolabel2
.n
- read next line from input and put to pattern space or exit if no more line from inputb label1
- jump tolabel1
:label2
- declare a label with namelabel2
n
- read next line from input and put to pattern space or exit if no more line from inputb label2
- jump tolabel2
Pseudo code
input = readLineFromInput() while (input != null) { patternSpace.append(input) if (patternSpace.contains("server-beta")) { while (true) { // label1 if (patternSpace.replace("192.168.0.1", "192.168.0.2")) { break // jump to label2 } /** start of n **/ display(patternSpace) patternSpace.clear() input = readLineFromInput() if (input == null) { exit } patternSpace.append(line) /** end of n **/ } while (true) { // label2 /** start of n **/ display(patternSpace) patternSpace.clear() input = readLineFromInput() if (input == null) { exit } patternSpace.append(line) /** end of n **/ } } display(patternSpace) patternSpace.clear() input = readLineFromInput() }
Delete lines matching pattern
Input file
aa1 bb2 cc3
Command
sed /bb/d file
Output
aa1 cc3
Delete n-th line
Input file
aa1 aa2 aa3 aa4 aa5
Command
# delete 2nd line sed 2d
Output
aa1 aa3 aa4 aa5
Insert before line
Input file
aa1 bb2 cc3
Command
sed "/bb/i bb_before" file
Output
aa1 bb_before bb2 cc3
Insert after line
Input file
aa1 bb2 cc3
Command
sed "/bb/a bb_after" file
Output
aa1 bb2 bb_after cc3
Use other delimiter
Input file
/aa/bb/cc/dd
Problem
It is too clumsy to escape slash.
sed 's/bb/bb1\/bb2\/bb3/' file
Command
It is clearer if #
is used.
sed 's#bb#bb1/bb2/bb3#' file
Output
/aa/bb1/bb2/bb3/cc/dd
Actually any character can be used.
These are all valid and produce same output.
# , is used sed 's,bb,bb1/bb2/bb3,' file # $ is used sed 's$bb$bb1/bb2/bb3$' file # a is used sed 'sabbabb1/bb2/bb3a' file
But you can't use character which is inside the pattern.
# b is used sed 'sbbbbbb1/bb2/bb3b' file # sed: -e expression #1, char 5: unknown option to `s' # 1 is used sed 's1bb1bb1/bb2/bb31' file # sed: -e expression #1, char 9: unknown option to `s'
Top comments (0)