如何在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
答案 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)
通过此算法可以有效解决任何文件大小的问题:
作为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