File1
内容:
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
File2
内容:
line1-file2 "25"
line2-file2 "24"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
perl/shell脚本执行后,File2
内容应变为:
line1-file2 "25"
line2-file2 "24"
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
File1
即,将in的内容粘贴到File2
包含“Pointer”的行之前。
答案1
该sed
实用程序有一个功能,可以就地进行修改:
sed -i -e '/Pointer/r file1' file2
但这让你指针内容上方的行file1
。简单来说就是延迟线输出:
sed -n -i -e '/Pointer/r file1' -e 1x -e '2,${x;p}' -e '${x;p}' file2
使用 GNU sed
:
sed '/Pointer/e cat file1' file2
根据手动的为了e [command]
:
请注意,与 r 命令不同,该命令的输出将立即打印; r 命令将输出延迟到当前周期结束。
答案2
不使用sed
或awk
.
首先,找到您的图案所在的行:
line=$(grep -n 'Pointer' file2 | cut -d ":" -f 1)
然后,使用3个命令输出想要的结果:
{ head -n $(($line-1)) file2; cat file1; tail -n +$line file2; } > new_file
这有访问 3 次的缺点file2
,但可能比 ased
的awk
解决方案更清晰。
答案3
awk
让这变得相当容易。
在文件前插入以下行:
awk '/Pointer/{while(getline line<"innerfile"){print line}} //' outerfile >tmp
mv tmp outerfile
要使内部文件在该Pointer
行之后打印,只需切换模式的顺序(您需要添加分号以获得默认操作),然后可以删除变量line
:
awk '//; /Pointer/{while(getline<"innerfile"){print}}' outerfile >tmp
mv tmp outerfile
正因为还没有人用过perl
,
# insert file before line
perl -e 'while(<>){if($_=~/Pointer/){system("cat innerfile")};print}' outerfile
# after line
perl -e 'while(<>){print;if($_=~/Pointer/){system("cat innerfile")}}' outerfile
答案4
一项简单的工作ed
:
ed -s file1 <<IN
/Pointer/-r file2
,p
q
IN
-r file1
将指定文件读入指定行之后,在本例中,该行是匹配 的第一行之前的行Pointer
。因此file2
,即使Pointer
出现在多行中,这也只会插入一次内容。如果你想在每个匹配行之前插入它,请添加g
lobal 标志:
ed -s file1 <<IN
g/Pointer/-r file2
,p
q
IN
如果您想就地编辑文件,请替换,p
为。w
接受的sed
答案确实适用于大多数情况,但如果标记位于最后一行,则该命令将无法按预期工作:它将File1
在标记之后插入 的内容。
我最初尝试过:
sed '/Pointer/{r file1
N}' file2
它也可以正常工作(就像r
在循环结束时发挥其魔力一样),但如果标记位于最后一行(N
最后一行之后没有分行),则会出现相同的问题。要解决这个问题,您可以在输入中添加换行符:
sed '/Pointer/{ # like the first one, but this time even if the
r file1 # marker is on the last line in File2 it
N # will be on the second to last line in
} # the combined input so N will always work;
${ # on the last line of input: if the line is
/^$/!{ # not empty, it means the marker was on the last
s/\n$// # line in File2 so the final empty line in the
} # input was pulled i\n: remove the latter;
//d # if the line is empty, delete it
}' file2 <(printf %s\\n)
这将file2
在每个匹配行之前插入内容。要仅在第一个匹配行之前插入它,您可以使用l
oop 并拉入n
ext 行,直到到达文件末尾:
sed '/Pointer/{
r file2
N
:l
$!n
$!bl
}
${
/^$/!{
s/\n$//
}
//d
}' file1 <(printf %s\\n)
使用这些sed
解决方案,您将失去就地编辑的能力(但您可以重定向到另一个文件)。