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)