1

I am writinig a BASH shell script on MINIX where I want to replace entirely a file's specific line by its number with a certain string, and this replacement to be overwriten to the original file. Not printed on the stdout.

The number of the line and the replacement string are variables of the script with the following names:

line (e.g. 8)
repstring (e.g. "134|Wan|Cho|1988-03-20")

So I m trying the following code:

sed -i "${line}s/.*/${repstring}/" $filename

But when I try to execute the script I get the message:

sed: unknown option -- i
usage:  sed [-aEnr] script [file ...]
        sed [-aEnr] [-e script] ... [-f script_file] ... [file ...]

Is it possible to make this file editing in another way?

p.s. I am aware of redirecting the output of the sed to a new file and then move the new file to the original, but I don't want to create any other files during the process.

thomas_p
  • 97
  • 1
  • 14
  • It seems that your -i parameter is not valid. Looking at the man pages of sed. The -i parameter requires an extension and in this case you did not add one. – Claudio Corsi Mar 20 '16 at 18:08
  • I just read about that here: http://www.grymoire.com/Unix/Sed.html#uh-62h But I alreade tried `pkgin update` and `pkgin install sed` but it says that database is up-to-date. So what is the proper way to install that extension manually? – thomas_p Mar 20 '16 at 18:18
  • @ClaudioCorsi the `-i` option does not require an extension in order to perform in-place editing, but adding an extension (eg. `-i.bak`) will create a backup of the original file, now having a `.bak` extension. – assefamaru Mar 20 '16 at 18:22
  • 1
    It says right in the error message, his version of `sed` doesn't support the `-i` option. It can't be used. – miken32 Mar 20 '16 at 18:23

2 Answers2

1

According to the documentation, MINIX uses a very minimal version of sed. If you want to stick with sed, just use redirection, and then move the output file to replace the old one.

sed "${line}s/.*/${repstring}/" "$filename" > /tmp/sed.tmp && mv /tmp/sed.tmp "$filename"

Or, use Perl:

perl -pi -e "if (\$.==$line) {s/.*/$repstring/ && end}" "$filename"

The variable $. represents the current line number.

miken32
  • 42,008
  • 16
  • 111
  • 154
  • Well this solution works properly. But is it possible to update the `sed` version MINIX uses in order to do this editing without creating any temporary files in the process? – thomas_p Mar 20 '16 at 18:28
  • You could likely download and compile the GNU version, or just use Perl. See my last edit from a few seconds ago. – miken32 Mar 20 '16 at 18:29
  • Well, I 'll try to download the GNU version in order to make it work and if I still can't fix it that way, I 'll use the redirection method you mentioned. I cannot use Perl in this project since I still have not been taught about it. Thanks for your time. – thomas_p Mar 20 '16 at 18:36
  • @thomas_p: you can't count on sed (even with the `-i` option) to update a file in place. To allow for massive appends or deletes, the software will open a new temp file at a different place on the disk, write the new version, then swap the tmpFile to the origFile . Good luck. – shellter Mar 21 '16 at 02:24
  • Oh, thanks for pointing that out. I finally ended up creating a temprary file to redirect the `sed` output and then swap it with the original one, as MINIX wouldn't support the -i option for `sed`. – thomas_p Mar 23 '16 at 17:57
1

First make sure what is a character you won't find in ${repstring}. When a / is part of the string, you would like to use some other unique character.

Can you try the old editor ed?

ed -s "${filename}" << EOF
${linenr}s/.*/${repstring}/g
w
q
EOF

When you don't know what would be the unique character, you can use

ed -s "${filename}"<< EOF
${linenr}c
${repstring}
.
w
q
EOF

But you really should be in control of repstring. Guess what happens with the next repstring:

repstring=".
!touch WarnedYou"
Walter A
  • 19,067
  • 2
  • 23
  • 43