将分组的文本行复制并粘贴到另一个文件中的优雅方式
Elegant way to copy and paste grouped lines of text into another file
假设我有两个文件。如何执行以下操作,即将标记的部分从一个文件复制到另一个文件的特定位置?一些 sed
命令可以完成这项工作吗?最实用的方法是什么?
文件#1:
This paragraph does not belong to the poem.
{ begin passage #1 }
When from a place he run away,
He never at the place did stay;
And while he run, as I am told,
He never stood still for young or old.
He often squeaked, and sometimes violent,
And when he squeaked he never was silent.
Though never instructed by a cat,
He knew a mouse was not a rat.
{ end passage #1 }
This as well does not.
文件#2:
There was a little guinea pig,
Who being little, was not big;
He always walked upon his feet,
And never fasted when he eat.
{ input passage #1 file #1 }
One day, as I am certified,
He took a whim, and fairly died;
And as I am told by men of sense,
He never has been living since.
我想将文件 #1 中的段落插入到文件 #2 的给定标记处。感谢您的帮助和想法!
正如您所问 "What is the most practical way",我的回答是 sed
和 awk
的混合,使用 shell 脚本将整个事情粘合在一起。
尝试仅使用 sed
来解决这个问题可能是可行的,但不值得花时间去弄明白。
几乎肯定可以进行进一步的优化,但我已尝试编写您可以理解的代码,而不是单行代码 ;-)。
#!/bin/ksh
sed -n '/^{ begin passage/,/^{ end passage /p' file_1 | sed '/^{/d' > /tmp/$$.segment
awk -v segFile="/tmp/$$.segment" '{
if ([=10=] ~ /^{ input passage/) {
while (getline < segFile > 0 ) {
print [=10=]
}
next
}
else {
print [=10=]
}
}' file_2
rm /tmp/$$.segment
输出
There was a little guinea pig,
Who being little, was not big;
He always walked upon his feet,
And never fasted when he eat.
When from a place he run away,
He never at the place did stay;
And while he run, as I am told,
He never stood still for young or old.
He often squeaked, and sometimes violent,
And when he squeaked he never was silent.
Though never instructed by a cat,
He knew a mouse was not a rat.
One day, as I am certified,
He took a whim, and fairly died;
And as I am told by men of sense,
He never has been living since.
如果需要,您可以将 #!/bin/ksh
更改为 #!/bin/bash
。
您可以 post-过滤您的输出以消除重复的空行,但不清楚您的最终需求是什么。
IHTH
这可能对你有用 (GNU sed):
sed -n '/{ begin/,/{ end/!b;//!p' file1 | sed -e '/{ input/r /dev/stdin' -e '//d' file2
过滤file1中的行并将它们插入到file2中。第一个 sed 命令的标准输出成为第二个 sed 命令的标准输入文件。在第二次 sed 调用中需要两个 sed 命令,因为 r
命令必须以换行符结束(或新的 -e
sed 命令)。第二个 sed 命令删除插入第一个文件行的行。
假设我有两个文件。如何执行以下操作,即将标记的部分从一个文件复制到另一个文件的特定位置?一些 sed
命令可以完成这项工作吗?最实用的方法是什么?
文件#1:
This paragraph does not belong to the poem.
{ begin passage #1 }
When from a place he run away,
He never at the place did stay;
And while he run, as I am told,
He never stood still for young or old.
He often squeaked, and sometimes violent,
And when he squeaked he never was silent.
Though never instructed by a cat,
He knew a mouse was not a rat.
{ end passage #1 }
This as well does not.
文件#2:
There was a little guinea pig,
Who being little, was not big;
He always walked upon his feet,
And never fasted when he eat.
{ input passage #1 file #1 }
One day, as I am certified,
He took a whim, and fairly died;
And as I am told by men of sense,
He never has been living since.
我想将文件 #1 中的段落插入到文件 #2 的给定标记处。感谢您的帮助和想法!
正如您所问 "What is the most practical way",我的回答是 sed
和 awk
的混合,使用 shell 脚本将整个事情粘合在一起。
尝试仅使用 sed
来解决这个问题可能是可行的,但不值得花时间去弄明白。
几乎肯定可以进行进一步的优化,但我已尝试编写您可以理解的代码,而不是单行代码 ;-)。
#!/bin/ksh
sed -n '/^{ begin passage/,/^{ end passage /p' file_1 | sed '/^{/d' > /tmp/$$.segment
awk -v segFile="/tmp/$$.segment" '{
if ([=10=] ~ /^{ input passage/) {
while (getline < segFile > 0 ) {
print [=10=]
}
next
}
else {
print [=10=]
}
}' file_2
rm /tmp/$$.segment
输出
There was a little guinea pig,
Who being little, was not big;
He always walked upon his feet,
And never fasted when he eat.
When from a place he run away,
He never at the place did stay;
And while he run, as I am told,
He never stood still for young or old.
He often squeaked, and sometimes violent,
And when he squeaked he never was silent.
Though never instructed by a cat,
He knew a mouse was not a rat.
One day, as I am certified,
He took a whim, and fairly died;
And as I am told by men of sense,
He never has been living since.
如果需要,您可以将 #!/bin/ksh
更改为 #!/bin/bash
。
您可以 post-过滤您的输出以消除重复的空行,但不清楚您的最终需求是什么。
IHTH
这可能对你有用 (GNU sed):
sed -n '/{ begin/,/{ end/!b;//!p' file1 | sed -e '/{ input/r /dev/stdin' -e '//d' file2
过滤file1中的行并将它们插入到file2中。第一个 sed 命令的标准输出成为第二个 sed 命令的标准输入文件。在第二次 sed 调用中需要两个 sed 命令,因为 r
命令必须以换行符结束(或新的 -e
sed 命令)。第二个 sed 命令删除插入第一个文件行的行。