0

I have these two sets of command lines:

make PREFIX=/usr                \
SHAREDIR=/usr/share/hwdata \
SHARED=yes
make PREFIX=/usr                \
SHAREDIR=/usr/share/hwdata \
SHARED=yes                 \
install install-lib

I want to insert a line before the second make PREFIX=/usr.

This is what I've tried:

sed -e "/make PREFIX=\/usr/i\  sed -e '/\\\\\$(DIRINSTALL) -m 755 \\\\\$(DESTDIR)\\\\\$(SBINDIR)/ s/^/#/' \\\\\n\      -e '/\\\\\$(DIRINSTALL) -m 755 \\\\\$(DESTDIR)\\\\\$(LIBDIR)/ s/^/#/' \\\\\n\      -e 's/pci \\\\\$(DESTDIR)\\\\\$(PKGCFDIR)/pci/' \\\\\n\      -i Makefile" \
 >> $Output

$Output is the name of the script file.

it creates the correct sed command (see below) (some of the \ have been lost in displaying here) but it puts the line above both patterns - of course. I've tried various refinements on the above but nothing has been successful. How do I insert it above only the second occurrence? I'm sorry, but Google hasn't enlightened me. I'm writing this in a Bash script so sed or awk would be easiest for me to apply. I don't know any Perl so would prefer not to use it.

Here is the line I wish to insert. This is the way it needs to look in the Bash script:

sed   -e '/\$(DIRINSTALL) -m 755 \$(DESTDIR)\$(SBINDIR)/ s/^/#/' \
      -e '/\$(DIRINSTALL) -m 755 \$(DESTDIR)\$(LIBDIR)/ s/^/#/' \
      -e 's/pci \$(DESTDIR)\$(PKGCFDIR)/pci/' \
      -i Makefile
5
  • 1
    Hi. Please post the desired output example. Also, I think the " is missing at the end. There are multiple ways to do your task. If you have only two sets, use tac to reverse lines, sed to insert at first pattern, then tac again. The better way is to add a flag in hold space on first pattern, so at the second pattern you realize it is time to do the insert operation.
    – seshoumara
    Oct 10, 2020 at 19:56
  • We also need to see the line you want to insert. Your sed command is unfinished, so that doesn't help.
    – terdon
    Oct 10, 2020 at 22:59
  • @user1375531 please edit your question and show us what your expected output is. Don't put it in a comment, add it to the question where it can be easily seen.
    – terdon
    Oct 11, 2020 at 9:57
  • Note that you can format your snippets as code by selecting them in the editing box and clicking on the {} button in the bar above it. Code formatting preserves any characters (verbatim), including backslashes.
    – fra-san
    Oct 11, 2020 at 11:27
  • check my solution .. just one line can fix this Oct 11, 2020 at 11:38

4 Answers 4

1

This should work... It skips the first occurrence

sed -i -E '0,/make PREFIX/! s/(make PREFIX)/\n\1/' file.txt

file.txt

make PREFIX=/usr
SHAREDIR=/usr/share/hwdata
SHARED=yes
make PREFIX=/usr
SHAREDIR=/usr/share/hwdata
SHARED=yes
install install-lib
1

heredocs << are a great n convenient way to avoid quoting and backslashing issues on the command line.

We pass a code to sed which looks for the first make command and then glides over to the next. At which point the insertion is done and from thereon it glides to the eof without bothering about anything else.

sed -f - file <<\eof 
  /make PREFIX=\/usr/!b
  :a;n;//!ba
  i\
sed -e '/\\$(DIRINSTALL) -m 755 \\$(DESTDIR)\\$(SBINDIR)/ s/^/#/' \\\
    -e '/\\$(DIRINSTALL) -m 755 \\$(DESTDIR)\\$(LIBDIR)/ s/^/#/' \\\
    -e 's/pci \\$(DESTDIR)\\$(PKGCFDIR)/pci/' \\\
-i Makefile
  :b;n;bb
eof

This is based on your expected output.

0

One way to do it with awk:

awk '
  index($0, "make PREFIX=/usr") && (++c == 2){
    print "sed -e \047/\\$(DIRINSTALL) -m 755 \\$(DESTDIR)\\$(SBINDIR)/ s/^/#/\047 \\"
    print "    -e \047/\\$(DIRINSTALL) -m 755 \\$(DESTDIR)\\$(LIBDIR)/ s/^/#/\047 \\"
    print "    -e \047/s/pci \\$(DESTDIR)\\$(PKGCFDIR)/pci/\047 \\"
    print "    -i Makefile"
  }
  1 # print current line
' file

If the string make PREFIX=/usr is present in the current line (index > 0), pre-increment variable c and compare it to 2. If the condition is true, print the string to insert. Then print the current line. The single quotes are written as octal \047.

1
  • Yes, brilliant. Works perfectly. Thanks a bunch. Oct 11, 2020 at 11:48
0

I take variable "contentneed_to_replace" to replace content before the line "make PREFIX"

for i in `sed -n '/make PREFIX/{;=;p}' o.txt| sed -n '1~2p'| sed -n '2p'`
do
contentneed_to_replace="praveen"
sed ''$i's/make PREFIX.*/'$contentneed_to_replace'\n&/g' o.txt
done

output

make PREFIX=/usr                \
 SHAREDIR=/usr/share/hwdata \
 SHARED=yes

 praveen
make PREFIX=/usr                \
 SHAREDIR=/usr/share/hwdata \
 SHARED=yes                 \
 install install-lib

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .