DEV Community

Franz Wong
Franz Wong

Posted on • Edited on

sed cookbook

Table of contents

Write the result to another file

Content of file_1 (before command is executed)

Hello World 
Enter fullscreen mode Exit fullscreen mode

Command

sed 's/Hello/Goodbye/;w file_2' file_1 
Enter fullscreen mode Exit fullscreen mode

Content of file_1 (after command is executed)

Hello World 
Enter fullscreen mode Exit fullscreen mode

Content of file_2 (after command is executed)

Goodbye World 
Enter fullscreen mode Exit fullscreen mode

Replace first occurrence on every

Input file

aa bb bb aa bb 
Enter fullscreen mode Exit fullscreen mode

Command

sed 's/bb/dd/' file 
Enter fullscreen mode Exit fullscreen mode

Output

aa dd bb aa dd 
Enter fullscreen mode Exit fullscreen mode

Replace values of all occurrences

Input file

aa bb bb aa bb 
Enter fullscreen mode Exit fullscreen mode

Command

sed 's/bb/dd/g' file 
Enter fullscreen mode Exit fullscreen mode

Output

aa dd dd cc dd 
Enter fullscreen mode Exit fullscreen mode

Replace value of first occurrence in the file

Input file

aa bb bb aa bb 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Output

aa dd bb cc bb 
Enter fullscreen mode Exit fullscreen mode

Replace all occurrences on n-th line

Input file

aa bb bb aa bb 
Enter fullscreen mode Exit fullscreen mode

Command

# replace all occurrences on 2nd line sed '2s/bb/dd/g' file 
Enter fullscreen mode Exit fullscreen mode

Output

aa dd dd aa bb 
Enter fullscreen mode Exit fullscreen mode

Replace all occurrences within a range of lines

Input file

aa1 aa2 aa3 aa4 aa5 
Enter fullscreen mode Exit fullscreen mode

Command

# replace occurrences from 2nd line to 4th line sed '2,4s/aa/dd/g' file 
Enter fullscreen mode Exit fullscreen mode

Output

aa1 dd2 dd3 dd4 aa5 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Command

# replace "1" with "10" on all the lines containing "b" sed '/b/s/1/10/g' file1 
Enter fullscreen mode Exit fullscreen mode

Output

a 1 a 2 a 1 x b 10 b 2 b 10 x c 1 c 2 c 1 x 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Command

# replace "1" with "10" on all the lines NOT containing "b" sed '/b/!s/1/10/g' file 
Enter fullscreen mode Exit fullscreen mode

Output

a 10 a 2 a 10 x b 1 b 2 b 1 x c 10 c 2 c 10 x 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Explanation

It uses the sed branching commands b and t.

  • /server-beta/! b - if pattern space doesn't contain server-beta, it will jump to the end of script.

  • :label1 - declare a label with name label1

  • s/192.168.0.1/192.168.0.2/ - Replace 192.168.0.1 with 192.168.0.2

  • t label2 - if the previous replacement is done, jump to label2.

  • n - read next line from input and put to pattern space or exit if no more line from input

  • b label1 - jump to label1

  • :label2 - declare a label with name label2

  • n - read next line from input and put to pattern space or exit if no more line from input

  • b label2 - jump to label2

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() } 
Enter fullscreen mode Exit fullscreen mode

Delete lines matching pattern

Input file

aa1 bb2 cc3 
Enter fullscreen mode Exit fullscreen mode

Command

sed /bb/d file 
Enter fullscreen mode Exit fullscreen mode

Output

aa1 cc3 
Enter fullscreen mode Exit fullscreen mode

Delete n-th line

Input file

aa1 aa2 aa3 aa4 aa5 
Enter fullscreen mode Exit fullscreen mode

Command

# delete 2nd line sed 2d 
Enter fullscreen mode Exit fullscreen mode

Output

aa1 aa3 aa4 aa5 
Enter fullscreen mode Exit fullscreen mode

Insert before line

Input file

aa1 bb2 cc3 
Enter fullscreen mode Exit fullscreen mode

Command

sed "/bb/i bb_before" file 
Enter fullscreen mode Exit fullscreen mode

Output

aa1 bb_before bb2 cc3 
Enter fullscreen mode Exit fullscreen mode

Insert after line

Input file

aa1 bb2 cc3 
Enter fullscreen mode Exit fullscreen mode

Command

sed "/bb/a bb_after" file 
Enter fullscreen mode Exit fullscreen mode

Output

aa1 bb2 bb_after cc3 
Enter fullscreen mode Exit fullscreen mode

Use other delimiter

Input file

/aa/bb/cc/dd 
Enter fullscreen mode Exit fullscreen mode

Problem

It is too clumsy to escape slash.

sed 's/bb/bb1\/bb2\/bb3/' file 
Enter fullscreen mode Exit fullscreen mode

Command

It is clearer if # is used.

sed 's#bb#bb1/bb2/bb3#' file 
Enter fullscreen mode Exit fullscreen mode

Output

/aa/bb1/bb2/bb3/cc/dd 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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' 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)