RE: [ILUG] sed challenge (really a shell question)

From: Stephen_Reilly at domain dell.com
Date: Fri 05 Apr 2002 - 14:34:50 IST


so ...

$ sed -e '2i\
> line1\
> line2' /etc/pam.d/su | cat > /etc/pam.d/su

or

$ sed -e '1a\
> line1\
> line2' /etc/pam.d/su | cat > /etc/pam.d/su

With the append option. It's unfortunate to use cat but otherwise the file
will overwrite itself. A gold star for anyone who can remove it without
writing to another file ... sed output redirection has often caused me
headaches in the past. Except with certain emulaters that just run things
sequentially ...

steve

-----Original Message-----
From: Brian Foster [mailto:blf at domain utvinternet.ie]
Sent: 05 April 2002 14:04
To: Irish Linux Users Group
Subject: Re: [ILUG] sed challenge (really a shell question)

  | Date: Fri, 5 Apr 2002 10:05:04 +0100
  | From: John Moylan <moylanj at domain rte.ie>
  |
  | I need to insert 2 lines at the top of a /etc/pam.d/su
  | after the header. I need to do this from the command
  | line - not a script, and I can not use any other files
  | for the insertion.
  |
  | I am trying to use sed with the i option, but it won't
  | work the way I think it should. Is it possible to use
  | it from the command line? if so how?

 1st, if you want to add the extra lines _after_ the header line(s?),
 you should probably use `a' (append after), not `i' (insert before).

 2nd, you don't state which shell is involved. unfortunately,
 the solution depends on the shell, as this question really is
 "how do I use literal backslashes (\) and newlines from my
 shell's interactive command line?"

 having said that, here's a solution for any Bourne-ish shell (i.e.,
 sh, ksh, bash, ..., &tc, but NOT C-shells (csh) and so on):

 $ sed '/RE/a\
> lineA\
> lineB' input_files... >output_file

 the leading `$ ' and `> ' are the Bourne-ish shell prompts (which
 you do not type; type everything else, including the backslashes
 and newlines).

 the `RE' is a regular expression which uniquely identifies the
 _last_ line in the header. alternatively, if you _know_ the last
 header line is, say, line 3, then you could use `3' rather than
 `/RE/' (and hence not run the risk of an inadvertent 2nd match).

 `lineA' is the first added line, and `lineB' the second (and so
 would become lines 4 and 5 if the last header line was 3). note
 that single-quotes in either line, or the RE, is Not A Good Idea
 (but can be done with additional effort).

 note the use of single-quotes (''), and all the backslashes.
 it can be done without using single-quotes, but they are the
 most convenient; here they mean (to the Bourne-ish shell) "all
 contained characters are to be taken literally". hence, the
 backslashes and newlines are passed to sed (and NOT interpreted
 by the Bourne-ish shell). which is what sed wants, as per the
 manual page. qed.

cheers!
        -blf-

p.s. since everyone(?) else seems to be suggesting non-sed
     multi-command single-line solutions, here's mine (untested),
     using the above header-ends-at-line-3 example:

( sed 3q input_file; echo lineA; echo lineB; sed 1,3d input_file)
>output_file

--
 Innovative, very experienced, Unix and      | Brian Foster    Dublin,
Ireland
 Chorus (embedded RTOS) kernel internals     | e-mail: blf at domain utvinternet.ie
 expert looking for a new position ...       | mobile: (+353 or 0)86 854
9268
  For a resume, contact me, or see my website  http://www.blf.utvinternet.ie
-- 
Irish Linux Users' Group: ilug at domain linux.ie
http://www.linux.ie/mailman/listinfo/ilug for (un)subscription information.
List maintainer: listmaster at domain linux.ie


This archive was generated by hypermail 2.1.6 : Thu 06 Feb 2003 - 13:15:51 GMT