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

时间:2013-02-16 12:01:43

标签: perl unix sed edit

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

背景:该文件是一个自动生成的文本文件,但我每次重新生成时都需要手动编辑它,以便在特定行之后添加4行。我可以保证这条线总是在文件中,但我不能保证它会是什么线,所以我希望根据这条线的位置添加额外的线而不是添加到固定的rownumber。我希望自动化这个过程,因为它是我构建过程的一部分。

我正在使用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 个答案:

答案 0 :(得分:2)

假设标记线包含fnord而没有其他内容;

awk '1;/^fnord$/{print "foo"; print "bar";
    print "baz"; print "quux"}' input >output

答案 1 :(得分:0)

将sed'一个带有正则表达式的命令用于需要匹配的行

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

答案 2 :(得分:0)

通过此算法可以有效解决任何文件大小的问题:

  1. 从原始文件中读取每一行并将其打印到临时文件。
  2. 如果最后一行是标记行,请将插入行打印到临时文件
  3. 打印剩余的行
  4. 将tempfile重命名为原始文件名。
  5. 作为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.
    

    TESTFILE:

    foo
    bar
    baz
    qux
    quux
    

    正则表达式是/^ba/

    用法:$ perl this_script.pl source-file

    处理后的测试文件:

    foo
    bar
    Yourstuff
    baz
    qux
    quux
    

答案 3 :(得分: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;
}

为了便于记录,我已将其拼写出来;你显然可以将它缩短为看起来更像是三重奏的答案。你可以这样调用:

$ 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