替换多个文件中的某一行

替换多个文件中的某一行

我有一个文件列表和相应的行号,我想在其中执行替换:

s/LOG.error/LOG.warn

其他地方也可能发生这种情况,但我不想打扰这些行。如何使用 find 和 sed 来实现这一点?

该文件的格式如下:

FooBar.java 125
FooBar.java 180
FooBar2.java 128

这是我在寻找方法时发现的:

cat filenames.txt | xargs sed -i '<get-line-number-here>s/LOG.error/LOG.warn' <get-file-name-here>

答案1

您需要按目标文件将文件拆分为多个分区,然后sed -i分别对每个文件执行操作。假设您已按文件名和行号按升序分组,则可以执行以下操作

awk '$1 != prev { if (prev) print "\047 " prev;
    prev=$1;
    printf "sed -i \047" }
  { print $2 "s/LOG\\.error/LOG.warn/" }
  END { if (prev) print "\047 " prev }' filenames.txt | sh

如果第一列中的文件名不是单个标记,那么这是一个快速而肮脏的黑客攻击,它将以有趣且可能危险的方式被破坏。

我们基本上将您的文本文件重构为一系列sed脚本。因此您的示例将变成

sed -i '125s/LOG\.error/LOG.warn
180s/LOG\.error/LOG.warn/
' FooBar.java
sed -i '128s/LOG\.error/LOG.warn/
' FooBar2.java

您会注意到,该脚本包含每个文件sh一个脚本。sed

如果您使用的是 *BSD 平台(包括 Mac OS),则需要将其更改sed -ised -i ''Awk 中的"sed -i \047\047"以便正确嵌入单引号而不干扰周围的 shell 引用(以便整行变成printf "sed -i \047\047 \047" }(sic))。

相关内容