Sed
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
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>