1

如何在 unix 中的特定行之后将文本行插入文件中?

背景:该文件是一个自动生成的文本文件,但每次重新生成它时我都必须手动编辑它,以便在特定行之后添加 4 个附加行。我可以保证这一行将始终在文件中,但我不能保证它将在哪一行,所以我希望根据这一行的位置添加额外的行,而不是添加到固定的行号。我想自动化这个过程,因为它是我构建过程的一部分。

我正在使用 Mac OSX,所以我可以使用 unix 命令行工具,但我对这些工具不是很熟悉,无法弄清楚如何做到这一点。

编辑

感谢您的解决方案,尽管我还没有设法让他们工作:

我尝试了 Sed 解决方案

sed -i '/<string>1.0</string>/ a <key>CFBundleHelpBookFolder</key>\
<string>SongKongHelp</string>\
<key>CFBundleHelpBookName</key>\
<string>com.jthink.songkong.Help</string>
' /Applications/SongKong.app/Contents/Info.plist

但得到错误

sed: 1: "/Applications/SongKong. ...": invalid command code S

我尝试了 bash 解决方案

#!/bin/bash

    while read line; do
      echo "$line"
      if [[ "$line" = "<string>1.0</string>"]]; then
        cat mergefile.txt    # or echo or printf your extra lines
      fi
    done < /Applications/SongKong.app/Contents/Info.plist

但有错误

./buildosx4.sh: line 5: syntax error in conditional expression: unexpected token `;'
./buildosx4.sh: line 5: syntax error near `;'
./buildosx4.sh: line 5: `  if [[ "$line" = "<string>1.0</string>"]]; then'

编辑 2 现在工作,我错过了一个空间

#!/bin/bash

    while read line; do
      echo "$line"
      if [[ "$line" = "<string>1.0</string>" ]]; then
        cat mergefile.txt    # or echo or printf your extra lines
      fi
    done < /Applications/SongKong.app/Contents/Info.plist
4

4 回答 4

2

假设标记线fnord只包含其他内容;

awk '1;/^fnord$/{print "foo"; print "bar";
    print "baz"; print "quux"}' input >output
于 2013-02-16T12:14:25.647 回答
0

使用带有正则表达式的 sed 'a 命令来匹配您需要匹配的行

sed -i '/the target line looks like this/ a this is line 1\
this is line 2\
this is line 3\
this is line 4
' FILENAME
于 2013-02-16T12:20:50.050 回答
0

该算法可以有效地解决任何文件大小的问题:

  1. 从原始文件中读取每一行并将其打印到临时文件中。
  2. 如果最后一行是标记行,则将插入行打印到临时文件
  3. 打印剩余的行
  4. 将临时文件重命名为原始文件名。

作为 Perl 脚本:

#!perl
use strict; use warnings;

$^I = ".bak"; # create a backup file

while (<>) {
  print;
  last if /regex to determine if this is the line/;
}

print <<'END';
Yourstuff
END

print while <>; # print remaining lines
# renaming automatically done.

测试文件:

foo
bar
baz
qux
quux

正则表达式是/^ba/.

用法:$ perl this_script.pl source-file

处理后的testfile:

foo
bar
Yourstuff
baz
qux
quux
于 2013-02-16T12:25:24.963 回答
0

另一种看待这种情况的方法是,您希望在其中一个文件中的某个时间点合并两个文件。如果您额外的四行在一个单独的文件中,您可以制作一个更通用的工具,如下所示:

#!/usr/bin/awk

BEGIN {
  SEARCH=ARGV[1];    # Get the search string from the command line
  delete ARGV[1];    # Delete the argument, so subsequent arguments are files
}

# Collect the contents of the first file into a variable
NR==FNR { 
  ins=ins $0 "\n";
  next;
}

1    # print every line in the second (or rather the non-first) file

# Once we're in the second file, if we see the match, print stuff...
$0==SEARCH {
  printf("%s", ins);    # Using printf instead of print to avoid the extra newline
  next;
}

为了便于记录,我已将其详细说明;您显然可以将其缩短为看起来更像 Triplee 的答案的内容。你会这样调用:

$ scriptname "Text to match" mergefile.txt origfile.txt > outputfile.txt

通过这种方式,您将拥有一个可用于在不同文件和不同文本上实现这种合并的工具。

或者,您当然可以在纯 bash 中执行此操作。

#!/bin/bash

while read line; do
  echo "$line"
  if [[ "$line" = "matchtext" ]]; then
    cat mergefile.txt    # or echo or printf your extra lines
  fi
done < origfile.txt
于 2013-02-16T13:03:47.100 回答