I can print the first line of a file using
sed -n 1p file.txt
I can delete the first line of a file using
sed -i 1d file.txt
Is there a way to print-and-delete in sed
? Kind of like a FIFO pop()
or Perl's shift
.
I can print the first line of a file using
sed -n 1p file.txt
I can delete the first line of a file using
sed -i 1d file.txt
Is there a way to print-and-delete in sed
? Kind of like a FIFO pop()
or Perl's shift
.
You can use the command w
to write some lines to a different output file. On Linux and many other unix variants, /dev/stdout
is the program's standard output, which isn't where sed writes with the -i
option. If your system doesn't have /dev/stdout
or a variant such as /dev/fd/1
, you can write to a named pipe.
sed -i -e '1 w /dev/stdout' -e '1d' file.txt
This answer is an extension of Gilles' answer.
Needing to write the address twice is not very DRY, and while it works fine for this example of just deleting the first line, that method becomes more problematic if you have a more complicated search pattern for lines you want to "extract" from a file. Instead of writing the address twice, you can use curly braces to do both the w
and d
commands on the same address. Using the original example, that would look like this:
sed -i -e '1{w /dev/stdout' -e 'd}' file.txt
or more generally:
sed -i -e '/some long regex/{w /dev/stdout' -e 'd}' file.txt
-e
says: " '-e SCRIPT' Add the commands in SCRIPT to the set of commands to be run while processing the input."
So, they're not standalone commands that are executed sequentially but separately, they are instead all run together in the same context, just like if they were on different lines in a script file specified with -f
, or separated with semicolons. This pattern is used with commands like w
and a
that can't really be terminated any other way in a one-liner than ending the expression and starting a new one.
– dhakimian
Jul 27 '20 at 16:37
Unfortunately this is not possible. Essentially, you are asking for the output from sed to go to two different places: you'd like the first line to be printed to the stdout of sed, and for the remaining lines to be placed back in the file itself. But the output of sed can only go to one place (by default it goes to stdout, and if you specify the -i
option it goes back into the file).
Fortunately, I can't see any downsides from running the two commands separately.
sed
I hadn't known.
– Andrew Cheong
Jan 08 '14 at 06:44
/dev/stdout
or not. GNUsed
(which you need for-i
) treats/dev/stdout
specially, it doesn't open the/dev/stdout
file. If it did and stdout went to a file, your command would overwrite that file on Linux (where/dev/stdout
is implemented as a symlink). – Stéphane Chazelas Jan 14 '14 at 14:21info --index-search='w (write file) command' sed
for details – Stéphane Chazelas Jan 14 '14 at 14:27