Remove paragraph from file
Solution 1
Actually, sed
can also take ranges. This command will delete all lines between Match user foo
and the first empty line (inclusive):
$ sed '/Match user foo/,/^\s*$/{d}' file
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Personally, however, I would do this using perl's paragraph mode (-00
) that has the benefit of removing the leading blank lines:
$ perl -00ne 'print unless /Match user foo/' file
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
In both cases, you can use -i
to edit the file in place (these will create a backup of the original called file.bak
):
sed -i.bak '/Match user foo/,/^\s*$/{d}' file
or
perl -i.bak -00ne 'print unless /Match user foo/' file
Solution 2
Slightly more complicated than terdon’s sed
answer:
awk '/foo/ {suppress=1} /^\s*$/ {suppress=0} !suppress' file.php
produces almost exactly the same result as terdon’s answer:
...
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
i.e., it deletes (suppresses) every line
starting with the one that matches foo
up to the first subsequent line that contains only whitespace.
Lines 8, 9, and 10, which are blank in the file.php
input file
(between user foo
and user bar
) come out in the output.
By contrast, terdon’s answer deletes every line
starting with the one that matches foo
up through the first subsequent line that contains only whitespace;
so line 8 is deleted, but 9 and 10 come through.
These are not exactly what the user asked for.
awk '/foo/ {suppress=1}
/^\s*$/ && suppress==1 {suppress=2}
/[^\s]/ && suppress==2 {suppress=0}
!suppress' file.php
is. (This is broken into multiple lines for readability;
it could be entered all on one line.)
When it sees foo
, it goes into suppress mode #1 (suppress=1
).
When it sees a blank line while in suppress mode #1,
it switches into suppress mode #2.
When it sees a non-blank line while in suppress mode #2,
it switches into mode 0.
Finally, it does the obvious — print lines that are not suppress
ed.
Related videos on Youtube
maxisme
Updated on September 18, 2022Comments
-
maxisme over 1 year
I have a file (
file.php
) like this:... Match user foo ChrootDirectory /NAS/foo.info/ ForceCommand internal-sftp AllowTcpForwarding no GatewayPorts no X11Forwarding no Match user bar ChrootDirectory /NAS/bar.co.uk/ ForceCommand internal-sftp AllowTcpForwarding no GatewayPorts no X11Forwarding no Match user baz ChrootDirectory /NAS/baz.com/ ForceCommand internal-sftp AllowTcpForwarding no GatewayPorts no X11Forwarding no
I am trying to write a bash script to delete one of the paragraphs.
So say I wanted delete the user
foo
from thefile.php
. After running the script, it would then look like this:... Match user bar ChrootDirectory /NAS/bar.co.uk/ ForceCommand internal-sftp AllowTcpForwarding no GatewayPorts no X11Forwarding no Match user baz ChrootDirectory /NAS/baz.com/ ForceCommand internal-sftp AllowTcpForwarding no GatewayPorts no X11Forwarding no
How could I go about doing this. I have thought about using
sed
but that only seems to be appropriate for one liners?sed -i 's/foo//g' file.php
And I couldn't do it for each individual line as most of the lines withing the paragraph are not unique! Any ideas?
-
Admin about 9 yearsSorry, I rejected your edit without realizing you were the OP. In any case, I don't like giving the
-i
switch without explicitly stating that it will change the original file. I have now included it. -
Admin about 9 yearsHaha fair enough! Thank you for answering!
-
-
Michaël Le Barbier almost 7 yearsNice little finite state automaton here.