Sed

From DikapediaV2
Jump to: navigation, search

ADD NOTES: https://stackoverflow.com/questions/29399790/comment-out-lines-in-fstab-with-bash-script
https://www.bitdoze.com/sed-insert-append-text/#appending-text-with-sed

You can use sed to print out specific lines of a file. I'm sure there's more you can do with sed but this is what I have for now.


How to remove a line that contains a string like "aws-replication" from a file:

# grep -i aws-replication test
disk:x:6:aws-replication
aws-replication:x:1001:


# sed -i  '/aws-replication/d' ./test 
# grep -i aws-replication test
(no output as lines were deleted)


Usage

$ cat file
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10

To print one line (5)

$ sed -n 5p file
Line 5

To print multiple lines (5 & 8)

$ sed -n -e 5p -e 8p file
Line 5
Line 8

To print specific range (5 - 8)

$ sed -n 5,8p file
Line 5
Line 6
Line 7
Line 8

To print range with other specific line (5 - 8 & 10)

$ sed -n -e 5,8p -e 10p file
Line 5
Line 6
Line 7
Line 8
Line 10 

To remove the last character in a file, and pipe the new output back to the file using tee:

$ sudo sed '$ s/.$//'  /etc/cloud/cloud.cfg.d/99-datasource.cfg | tee /etc/cloud/cloud.cfg.d/99-datasource.cfg
'datasource_list': [
               'Ec2',
               'None'
           ]

To comment out a particular line or add something in front of a line:

$ cat testfile 
1
2
3
4

$ sed -i '2 s/^/#/' testfile 

$ cat testfile 
1
#2
3
4

To comment out multiple lines (i.e. lines 2 through 4):

$ cat testfile 
1
2
3
4

$ sed -i '2,4 s/^/#/' testfile 

$ cat testfile 
1
#2
#3
#4

$ sed '/AllowUsers/s/$/ centos2/' testfile

1
#2
#3
#4
AllowUsers ec2-user centos2

How to replace words/characters in a file


  • "-i means to do an in-place edit. Without -i, then it doesn't make an actual edit but it will print the result. Use without -i for testing purposes is very helpful.

sed -i s/A/B/g means replace A with B:

# cat test.file
linux
 
# sed -i s,linux,linux_replaced,g test.file

# cat test.file
linux_replaced

------- Alternative:

# sed -i s/linux_replaced/linux/g test.file

# cat test.file
linux

How to replace strings with special characters

This replaces the string UUID=asfdsffd-a264-4fe2-84dc-33de230c4200 with /dev/mapper/vgroot-lvroot.

sed -i "s/UUID=asfdsffd-a264-4fe2-84dc-33de230c4200/\/dev\/mapper\/vgroot-lvroot/g" <file>

How to replace long strings with spaces

# cat test.file 
linux /vmlinuz-3.10.0-1160.21.1.el7.x86_64 root=/dev/mapper/vglocal00-root00 ro crashkernel=auto biosdevname=1 modprobe.blacklist=mpt3sas net.ifnames=0 nomodeset rdblacklist=bfa,lpfc consoleblank=0 LANG=en_US.UTF-8 console=ttyS0 rd_NO_LVMCONF rd.lvm.conf=0

# sed "s:crashkernel=auto biosdevname=1 modprobe.blacklist=mpt3sas net.ifnames=0 nomodeset rdblacklist=bfa,lpfc consoleblank=0 LANG=en_US.UTF-8 ::g" test.file 
linux /vmlinuz-3.10.0-1160.21.1.el7.x86_64 root=/dev/mapper/vglocal00-root00 ro console=ttyS0 rd_NO_LVMCONF rd.lvm.conf=0

----- or with -i ------

# sed -i "s:crashkernel=auto biosdevname=1 modprobe.blacklist=mpt3sas net.ifnames=0 nomodeset rdblacklist=bfa,lpfc consoleblank=0 LANG=en_US.UTF-8 ::g" test.file 

# cat test.file 
linux /vmlinuz-3.10.0-1160.21.1.el7.x86_64 root=/dev/mapper/vglocal00-root00 ro console=ttyS0 rd_NO_LVMCONF rd.lvm.conf=0

References: https://unix.stackexchange.com/questions/288521/with-the-linux-cat-command-how-do-i-show-only-certain-lines-by-number

How to add a character at the beginning of a line that contains a specific string

This will add a '#' at the beginning of the lines that contain the string 'asfdsffd-a264-4fe2-84dc-33de230c4200'.

sed -i '/asfdsffd-a264-4fe2-84dc-33de230c4200/ s/^/#/' ./etc/fstab


How to "append"/replace a string after finding a match

Template:

sed -i '/<find_line_that_matches_this_string/ s/<string_to_replace>/<replacement_string>/g' <file>
sed -i '/X/ s/Y/Z/g' <file>
  • Find line that has X. Then replace Y with Z in that line.

This will find the line with "zzzsdfsf-a264-4fe2-84dc-123213124131", and replace "defaults" with "defaults,x-systemd.device-timeout=300":

$ cat fstab
UUID=77777f7f-b4f4-4ee4-b03f-c07c3f6f9act   /   xfs defaults    0   0
UUID=fdsa1389-b288-4175-ba95-fdsa43fdsf23   /boot   xfs defaults    0   0
UUID=abcdefgf-5022-1212-8cae-32424324fds3   /var  xfs defaults    0   0
UUID=zzzzzzzz-27ff-4732-8a24-8a2432434324   swap    swap    defaults    0   0
UUID=zzzsdfsf-a264-4fe2-84dc-123213124131   /test   xfs defaults    0   0

$ sed '/zzzsdfsf-a264-4fe2-84dc-123213124131/ s/defaults/defaults,x-systemd.device-timeout=300/g' fstab
UUID=77777f7f-b4f4-4ee4-b03f-c07c3f6f9act   /   xfs defaults    0   0
UUID=fdsa1389-b288-4175-ba95-fdsa43fdsf23   /boot   xfs defaults    0   0
UUID=abcdefgf-5022-1212-8cae-32424324fds3   /var  xfs defaults    0   0
UUID=zzzzzzzz-27ff-4732-8a24-8a2432434324   swap    swap    defaults    0   0
UUID=zzzsdfsf-a264-4fe2-84dc-123213124131   /test   xfs defaults,x-systemd.device-timeout=300    0   0


https://www.gnu.org/software/sed/manual/html_node/The-_0022s_0022-Command.html

https://www.theunixschool.com/2014/08/sed-examples-remove-delete-chars-from-line-file.html

How to target a specific String and insert a new string between some other character/string


In this example, we will use the following list as an example:

"Budapest": [ 
      "abc", 
      "def", 
      "ghi", 

  ], 
"ExtensionInstallAllowlist": [
      "abc", 
      "def", 
      "ghi", 

  ],

So how can you insert a new string at the end of the "ExtensionInstallAllowlist" list, but before the "]," if there are multiple strings ( "ExtensionInstallAllowlist" vs "Budapest" ) to differentiate from?

You can target the "ExtensionInstallAllowlist" list specifically and insert a new string before the ], using the following sed command:

sed -i '/"ExtensionInstallAllowlist": \[/,/\],/s/\(\s*\],\)/      "new_string",\n\1/' your_file.json

Explanation:

  • -i: Edits the file in place.
  • /"ExtensionInstallAllowlist": \[/,/\],/: Searches between the start of the "ExtensionInstallAllowlist" list and the closing ],.
  • s/\(\s*\],\)/ "new_string",\n\1/: Substitutes the closing ], with the new string followed by a newline and the original ],.
    • The \1 is a "backreference" that refers to what was captured (or matched). In this case, the \1 refers to the (\s*\],\) which is the closing bracket ],. So it inserts the string\n before that.
    • Adjust spaces to match the indentation.
  • your_file.json: The file where the change will be made.
  • Replace "new_string" with the actual string you want to add, and your_file.json with the path to your file.


sed: -e expression #1, char 193: unknown option to `s'


If you get the error sed: -e expression #1, char 193: unknown option to `s', likely there is some syntax issue like a /. You would have to use \ delimiter like:

sed '/vmlinuz-/ s/something\/to\/replace/rd.lvm.vg=VG01/g' grub.cfg
  • This replaces "something/to/replace" with rd.lvm.vg=VG01
  • Another example. Trying to replace a string that has 'goodboy':
sed s,\'\goodboy\'\,,g <file>
  • Another example if you are trying to replace a string with another string that has a ',' (use: \\,\\)
sed s,<string_to_replace>,\'hd0\\,\\gpt2\',g <file>