Running Fedora 25 server edition. sed --version
gives me sed (GNU sed) 4.2.2
along with the usual copyright and contact info. I've create a text file sudo vi ./potential_sed_bug
. Vi shows the contents of this file (with :set list
enabled) as:
don't$
delete$
me$
please$
I then run the following command:
sudo sed -n -i.bak /please/a\testing ./potential_sed_bug
Before we discuss the results; here is what the sed man page says:
-n, --quiet, --silent suppress automatic printing of pattern space
and
-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if extension supplied). The default operation mode is to break symbolic and hard links. This can be changed with --follow-symlinks and --copy.
I've also looked other sed command references to learn how to append with sed. Based on my understanding from the research I've done; the resulting file content should be:
don't
delete
me
please
testing
However, running sudo cat ./potential_sed_bug
gives me the following output:
testing
In light of this discrepancy, is my understanding of the command I ran incorrect or is there a bug with sed/the environment?
Sed Command to Delete Lines: Sed command can be used to delete or remove specific lines which matches a given pattern or in a particular position in a file. Here we will see how to delete lines using sed command with various examples.
To delete a line, we'll use the sed “d” command. Note that you have to declare which line to delete. Otherwise, sed will delete all the lines.
SED is a text stream editor used on Unix systems to edit files quickly and efficiently. The tool searches through, replaces, adds, and deletes lines in a text file without opening the file in a text editor. Learn how to use the sed command and its options through easy-to-follow examples.
N command reads the next line in the pattern space. d deletes the entire pattern space which contains the current and the next line. Using the substitution command s, we delete from the newline character till the end, which effective deletes the next line after the line containing the pattern Unix.
tl;dr
Don't use -n
with -i
: unless you use explicit output commands in your sed
script, nothing will be written to your file.
Using -i
produces no stdout (terminal) output, so there's nothing extra you need to do to make your command quiet.
By default, sed
automatically prints the (possibly modified) input lines to whatever its output target is, whether implied or explicitly specified: by default, to stdout (the terminal, unless redirected); with -i
, to a temporary file that ultimately replaces the input file.
In both cases, -n
suppresses this automatic printing, so that - unless you use explicit output functions such as p
or, in your case, a
- nothing gets printed to stdout / written to the temporary file.
p
, a
, i
and c
do not print to the pattern space (for potential subsequent modification), they print directly to the target stream / file, which is why a\testing
was able to produce output, despite the use of -n
.Note that with -i
, sed
's implicit printing / explicit output commands only print to the temporary file, and not also to stdout, so a command using -i
is invariably quiet with respect to stdout (terminal) output - there's nothing extra you need to do.
To give a concrete example (GNU sed
syntax).
Since the use of -i
is incidental to the question, I've omitted it for simplicity. Note that -i
prints to a temporary file first, which, on completion, replaces the original. This comes with pitfalls, notably the potential destruction of symlinks; see the lower half of this answer of mine.
# Print input (by default), and append literal 'testing' after
# lines that contain 'please'.
$ sed '/please/ a testing' <<<$'yes\nplease\nmore'
yes
please
testing
more
# Adding `-n` suppresses the default printing, so only `testing` is printed.
# Note that the sequence of processing is exactly the same as without `-n`:
# If and when a line with 'please' is found, 'testing' is appended *at that time*.
$ sed -n '/please/ a testing' <<<$'yes\nplease\nmore'
testing
# Adding an unconditional `p` (print) call undoes the effect of `-n`.
$ sed -n 'p; /please/ a testing' <<<$'yes\nplease\nmore'
yes
please
testing
more
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With