使用 sed 在模式的第二次出现处插入一行

使用 sed 在模式的第二次出现处插入一行

我有这两套命令行:

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

我想在第二个之前插入一行make PREFIX=/usr

这是我尝试过的:

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是脚本文件的名称。

它创建了正确的 sed 命令(见下文)(一些 \ 在显示时丢失了),但它把该行放在了两种模式之上 - 当然。我已经尝试了上述各种改进,但没有成功。如何将其插入到第二次出现的上方?抱歉,谷歌还没有启发我。我正在 Bash 脚本中编写此内容,因此 sed 或 awk 对我来说最容易应用。我不懂 Perl,所以不想使用它。

这是我要插入的行。这是 Bash 脚本中需要的样子:

sed   -e '/\$(DIRINSTALL) -m 755 \$(DESTDIR)\$(SBINDIR)/ s/^/#/' \
      -e '/\$(DIRINSTALL) -m 755 \$(DESTDIR)\$(LIBDIR)/ s/^/#/' \
      -e 's/pci \$(DESTDIR)\$(PKGCFDIR)/pci/' \
      -i Makefile

答案1

这应该有效...它会跳过第一次出现

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

文件.txt

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

答案2

heredocs <<是避免命令行上引用和反斜杠问题的一种非常方便的方法。

我们将代码传递给 sed,它会查找第一个 make 命令,然后跳到下一个命令。此时插入完成,从那时起它滑向 eof,而不关心其他任何事情。

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

这是基于您的预期输出。

答案3

一种方法是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

如果该字符串make PREFIX=/usr存在于当前行中(索引 > 0),则预递增变量c并将其与 进行比较2。如果条件为真,则打印要插入的字符串。然后打印当前行。单引号写成八进制\047

答案4

我使用变量“contentneed_to_replace”来替换“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

输出

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

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

相关内容