【问题标题】:How do insert lines of text into file after a particular line in unix [duplicate]如何在unix中的特定行之后将文本行插入文件[重复]
【发布时间】:2013-02-16 12:01:42
【问题描述】:

如何在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

【问题讨论】:

  • 如何这个文件是自动生成的?你能修好发电机吗?
  • 不,我不能,发电机不是我提供的,也许从长远来看它会被修复(我提出了一个问题)但在短期内不会。
  • 您是否尝试过搜索?这是一个很常见的问题。

标签: perl unix sed edit


【解决方案1】:

假设标记行包含fnord,没有其他内容;

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

【讨论】:

  • +1 表示该方法,但您需要在 1 之后使用分号。
  • 啊,是的,感谢您的修复。
  • +1,但可以更简单:printf "foo\nbar\n" 甚至system( "cat repl-file" )
【解决方案2】:

查看此问题的另一种方法是,您希望在其中一个文件的某个位置合并两个文件。如果您额外的四行在一个单独的文件中,您可以制作一个更通用的工具,如下所示:

#!/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

【讨论】:

  • 尝试了您的脚本,但出现错误 ./buildosx4.sh:第 5 行:条件表达式中的语法错误:意外令牌 ;' ./buildosx4.sh: line 5: syntax error near ;' ./buildosx4.sh:第 5 行:` if [[ "$line" = "1.0"]];那么'
  • @PaulTaylor - 我从您更新的问题中看到您缺少]] 之前的空格。你需要那个空间。
  • 啊,谢谢你现在有效
【解决方案3】:

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

  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

处理后的测试文件:

foo
bar
Yourstuff
baz
qux
quux

【讨论】:

  • 好吧,你去吧:perl、awk 或 sed。任你选!
  • 您可能应该转义目标正则表达式以避免对元字符进行评估。
【解决方案4】:

使用带有正则表达式的 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

【讨论】:

  • 我喜欢这个解决方案,除了我喜欢将行保存在另一个文件中的 ghotis 解决方案,您的解决方案可以修改为从文件中获取 4 行吗?
  • 它对我来说失败了,错误 sed: 1: "/Applications/SongKong. ...": invalid command code S
  • 这对 Paul 来说失败了,因为 -i 不是标准的 sed。它适用于 gnu sed,但不是所有 sed
  • @William Pursell - 谢谢这似乎是 unix 的主要问题,尤其是 linux
  • 问题不在于unix,而在于用户不关注标准。 Linux 不是 unix。
猜你喜欢
  • 1970-01-01
  • 2013-06-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多