You are not logged in.
Pages: 1
Topic closed
Hi,
I'm just figuring out if there's a workaround for this behavior using sed:
Creating or resetting 'myfile' (0 byte file):
$ > myfile
using:
$ sed -i '1i text' myfile
or even:
$ sed -i '1s/^/text\n/' myfile
Doesn't work, 'myfile' is still empty.
If I create or reset 'myfile' this way (1 byte file):
$ echo > myfile
sed is working properly, but counting lines with 'cat myfile | wc -l' returns always actual lines of text +1.
Is this the normal behavior of sed?
I cant't find it nowhere...
"Greetings from the Banana Republic"
Offline
For a file that has no first line, the address "1" won't match anything, so the insert or substitute command is never executed. With the echo, you write a newline to the file, giving the sed expression a line to match on. Then you insert another newline, increasing the line count (which you can check with `wc -l myfile` btw, no need for cat).
sed is line oriented but you want to use it on a file without any lines for some reason. There might be a way I don't know of, but it's still a strange thing to do. Why not simply use echo for this? Or what are you really trying to do?
Offline
@Raynman, thank you for the extremely clear answer.
The correct question should have been:
"is there a way to insert a line at the beginning of a zero-sized file using sed?"
Answer: no.
My goal is to find an universal way to insert a line at the beginning of a file, no matter its size.
Yes, right now I'm using 'echo' to do the job, appending new lines at the bottom of the file, and then using 'tac' instead of 'cat'.
"Greetings from the Banana Republic"
Offline
You could also handle an empty file as a special case in your script (then echo else sed) or look at answers to similar questions such as http://superuser.com/q/246837
Offline
Yes, I know.
At the moment the upside-down solution is the simplest, by far.
$ > myfile
0 byte!
$ echo "three" >> myfile
$ echo "two" >> myfile
$ echo "one" >> myfile
Using 'tac' instead of 'cat':
$ tac myfile
one
two
three
$ tac myfile | wc -l
3
Technically the topic is not solved until (if ever) sed can handle that...
Bye
"Greetings from the Banana Republic"
Offline
I think it would help if you told us what you are trying to accomplish. Maybe someone knows another way/different tool to do just what you want.
If I understand your 'upside' down with tac correctly you try to insert a line at the top of the file even if it is an empty file.
JFTR:
$ tac myfile | wc -l
No piping needed here.
I put at button on it. Yes. I wish to press it, but I'm not sure what will happen if I do. (Gune | Titan A.E.)
Offline
( echo insert a line ; cat file ) > file.tmp && mv file.tmp file || rm file.tmp
Appending at the bottom is nicer, does not require entire file to be re-written. Makes reading and printing out backwards more expensive though.
Offline
AWK solution, for the pipe filter scenario instead of editing in place. Let's suppose you want to prefix the lines with "x" (even if there is only a "non-line"):
$ code='BEGIN{t="x";printf(t)}{if(NR>1){sub(/^/,t)}print}'
on real lines:
$ seq 3 | awk "$code"
x1
x2
x3
on empty file:
$ cat /dev/null | awk "$code"; echo
x
(Note that no newline is appended, so the echo command was added for clarity)
If you really need in-place editing, there's GNU awk (gawk) and has a module for that (-i inplace), however printing from the BEGIN section does write to stdout instead to the file (version 4.1.4, not sure if it is a bug).. so i could not get it working correctly.
If you really have to use sed, i think it's impossible - its universe is non-empty sequence of lines.
And i wonder if the awk code can be made yet shorter - i use Perl much more, but it is not present on the platform i was solving the problem on: Plan 9.
Last edited by mykhal (2016-10-08 10:59:28)
Offline
Is touch not an option?
% touch myfile
% wc -l myfile
0 myfile
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
Ed will do exactly what you ask for:
echo -e "0a\nYour line here\n.\nw" | ed -s myfile
However, I'd like to echo Raynman's earlier question "What are you really trying to do?"
I sense a big X Y question here, and there's likely a far better approach to your end goal.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
If you would really like to use sed, you can without the -i option:
sed : <(echo '#!/bin/bash') myfile
Offline
Do not necrobump old threads - especially for "solutions" that will not work on arch linux.
Closed.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Pages: 1
Topic closed