Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

"13. cat file | sed s/foo/bar/ > file

   You cannot ..."
With sed, in some cases, you can. One of the differences between Linux-provided sed and BSD-provided sed is the -a option.

FreeBSD manpage:

"-a The files listed as parameters for the "w" functions are created (or truncated) before any processing begins, by default. The -a option causes sed to delay opening each file until a command containing the related "w" function is applied to a line of input."

So let's say you have a file

   cat > file
   sandfoo
   ^D
 
BSD-provided sed

   cat file|sed -na 's/foo/bar/;H;$!d;g;w'file 
The replacement is made without any temp file.

Note this example will add a blank line at the top.

Why use sed? sed is part of BSD base system, the toolchain^1 and install images thus it can easily be utilised early in boot process. I am not aware that "sponge" is part of any base system.

1. NetBSD's toolchain can be reliably cross-compiled on Linux.



An easier way to do the same thing but for any tool is `cat file | sed 's/foo/bar/' | sponge file`


Good old moreutils:)


what is wrong with the '-i' option?

-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if SUFFIX supplied)


sed -i creates a temp file. Needs additional storage space the size of the file.

This can pose a problem with large files on smaller computers with limited storage and memory.

In the past, some BSD seds (other than FreeBSD) did not have the -i option.

Also worth noting that "sponge", unlike sed, apparently reads the entire file into memory. For a large file, this would require enough RAM to fit the entire file.


Try `sed -i ""` to avoid creating a backup.


When you use sed -i, a temporary file is always created.

Using FreeBSD as an example, see references to "tmpfname" in main.c:

https://raw.githubusercontent.com/freebsd/freebsd/master/usr...

The naming scheme differs between seds. GNU prefixes the name with "sed" while BSD encloses it between two "!"'s.

To see the name of the temporary file on BSD, something like

  ktrace sed -i 's/foo/bar/' file
  kdump ktrace.out|sed -n '/NAMI/p'




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: