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 '20 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 '20 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 '20 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 '20 at 11:27
  • check my solution .. just one line can fix this – Sandeep Kothari Oct 11 '20 at 11:38
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. – user1375531 Oct 11 '20 at 11:48
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

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
0

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

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.