8

Say I had a block of text in the ~/.bashrc:

#~/.bashrc
# ...some commands...

# aliases
alias suicide='sudo rm -rf /'
# end aliases

# other commands

I wish to replace that block of text with some other text contained between two markers in another file: stuff-to-place-in-bashrc.txt

# stuff-to-place-in-bashrc.txt
# ...stuff...

# aliases
alias ldir='ls * -d'
alias ithinklifeisworthliving='echo all good'
# end aliases

# ...more stuff...

I've tried

 sed -ne 's/# aliases\s+\(.*\)\s+# end aliases/\1/' stuff-to-place-in-bashrc.txt

But I'm really swinging in the dark here. Could someone help me out?

  1. How do I extract the text from the stuff-to-place-in-bashrc.txt?

  2. How do I replace the other section in ~/.bashrc with the extracted text from question 1?

Edit

Thanks for the updates guys, those wondering why i would want something like this:

allows for cherry-picked updates to script files without overwritting user-made additions. useful for shared and frequently updated standard operating environments (like my last job at Tyro that coded with XP).

go crazy guys.

9

Ed is the standard editor, because you can use it to develop ed scripts and let it do its work, as you tested before, interactively. For small files like .bashrc or any code text, ed is performant because it reads the whole file in one rush and works with the buffer. For the same reason you should not use ed for big files like log files.

But with an ed script, your job is done in no time:

ed ~/.bashrc<<EOF
/^# aliases
+,/^# end aliases/-1d
-r !sed -n '/^# aliases/,/^# end aliases/p' stuff-to-place-in-bashrc.txt|grep -v '^#'
w
q
EOF

I use similar scripts to automatically tune configuration files, such als .asoundrc for different environments I take my laptop to.

The best document about ed comes as a simple manual page from the very cool PLAN9 system. I translated it to a ed.ps postscript document. If you are interested in PLAN9 you should check 9front and http://cat-v.org/ as the original bell labs version is still maintained but has a very simple filesystem.

A final word about editor wars, emacs, vim and the like: acme rules!

  • Thanks for the answer, It has worked, however I'm not sure what the syntax is. Does it use regex or something more specific to ed? looks like there are vim like commands (w,q) – thenaglecode Jun 25 '15 at 3:35
  • It uses regexes (/^# aliases, and /^# end aliases/), and the other commands are Vi/Ed. See, for example, vimhelp.appspot.com/cmdline.txt.html#%3Arange for +, /^# end aliases/. – muru Jun 25 '15 at 3:37
  • 1
    see info Ed on your system (hopefully). I don't know why modern linux distributions don't install this cool editor. w and q are write and quit commands. And ed works very similar to sed with regexes. There is a reason why the names sound that similar. d means delete the adressed lines, -r reads into the previous line the results of the ! command that follows. I shortend the filenames on the edit, as I'm so lazy typing this early morning. – ikrabbe Jun 25 '15 at 3:41
  • 1
    @thenaglecode see my last edit. I had to test that before I posted it. – ikrabbe Jun 25 '15 at 3:44
  • 1
    @thenaglecode The one and only really good pages about ed I ever needed was the ed(1) page from plan9: man.cat-v.org/plan_9/1/ed I can send you a postscript version if you like. As we are just talking about plan9, see the acme Editor too. If you get used to that, you will never use something else. Of course it's best to use a plan9 system, for example as a virtual machine inside your linux box, but the p9p port for unix is great too. (There are little differences between plan9 ed and gnu ed!) – ikrabbe Jun 25 '15 at 4:08
2
set /^\#aliases/  /^\#end\ aliases/
sed -ne"$1,$2"'s/\\\{0,1\}/&&/gp' <stuff_to_place...rc |
sed -e"$1,$2c\" -f- ./infile >./outfile

If you want to edit the file in-place ed is a very good solution. If you want to edit it in-stream, use sed. Avoid sed -i.

0

Sure, you can do this with ed alone, no need for additional tools:

ed -s stuff_to_place.txt<<\IN
1,/# aliases/d
/# end aliases/,$d
,d
.r /home/username/.bashrc
/# aliases/x
.t.
.,/# end aliases/-d
,p
q
IN

if you're happy with the result, replace ,p with w /home/username/.bashrc to write the changes to ~/.bashrc (note the full path used with r and w; you can simply use .bashrc if it's in cwd).
How this works: we first delete the unneeded lines from stuff_to_place.txt. Then we delete the remaining ones (the aliases) with ,d. The text buffer is now empty while the cut buffer contains the lines we want. We then read the content of .bashrc into the text buffer, put the content of the cut buffer (x) to after the /# aliases/ line, duplicate the last line that was pasted (.t.) then delete from the duplicated line up to but not including /# end aliases/ and finally print or write changes and quit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.