我想用其他文件替换所有包含Test.bundle的行(这些行分组在一个块中(
来自
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundleone.png" />
<BundleResource Include="ResourcesTest.bundletwo.png" />
<BundleResource Include="ResourcesTest.bundlethree.png" />
</ItemGroup>
至
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundlefour.png" />
<BundleResource Include="ResourcesTest.bundlefive.png" />
<BundleResource Include="ResourcesTest.bundlesix.png" />
<BundleResource Include="ResourcesTest.bundleseven.png" />
</ItemGroup>
我做了什么
res=$(find Resources/Test.bundle -type f | sed 's/\///g' | xargs -I {} echo "<BundleResource Include="{}" />") #get new files, change path delimiters, wrap file names in output pattern
sed -E -i '' '/Test.bundle/,/ItemGroup/c
BUNDLE_PLACEHOLDER' file.ext #remove whole block from first line containing Test.bundle to closing ItemGroup and replace with placeholder
sed -E -i '' "s:BUNDLE_PLACEHOLDER:$res:" file.ext #replace with new block
由于"extra characters after at the end of c command"
的原因,我无法在第三个命令中一次更改它,所以我将它更改为试图在下一个命令中替换的字符串占位符。这也是由于unescaped newline inside substitute pattern
而失败的,我目前正在尝试解决这个问题。还缺少稍后将添加的结束ItemGroup标记。
使用sed还有其他选择吗?
我可以只捕获包含Test.bundle的组而不捕获正在关闭的ItemGroup吗?
如何转义换行符以满足替换模式?
目前尚不清楚您真正想要匹配的内容,但这可能是您想要的:
awk '
NR==FNR {
new = new $0 ORS
next
}
/Test.bundle/ {
printf "%s", new
new = ""
next
}
{ print }
' new old
例如:
$ cat old
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundleone.png" />
<BundleResource Include="ResourcesTest.bundletwo.png" />
<BundleResource Include="ResourcesTest.bundlethree.png" />
</ItemGroup>
$ cat new
<BundleResource Include="ResourcesTest.bundlefour.png" />
<BundleResource Include="ResourcesTest.bundlefive.png" />
<BundleResource Include="ResourcesTest.bundlesix.png" />
<BundleResource Include="ResourcesTest.bundleseven.png" />
$ awk '
NR==FNR {
new = new $0 ORS
next
}
/Test.bundle/ {
printf "%s", new
new = ""
next
}
{ print }
' new old
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundlefour.png" />
<BundleResource Include="ResourcesTest.bundlefive.png" />
<BundleResource Include="ResourcesTest.bundlesix.png" />
<BundleResource Include="ResourcesTest.bundleseven.png" />
</ItemGroup>
首先,sed
并不是您的最佳选择,但由于您要求提供sed
这是一个粗糙的第一回合。
$: cat new
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundlefour.png" />
<BundleResource Include="ResourcesTest.bundlefive.png" />
<BundleResource Include="ResourcesTest.bundlesix.png" />
<BundleResource Include="ResourcesTest.bundleseven.png" />
</ItemGroup>
$: cat old
stuff before
...
more stuff
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundleone.png" />
<BundleResource Include="ResourcesTest.bundletwo.png" />
<BundleResource Include="ResourcesTest.bundlethree.png" />
</ItemGroup>
stuff after
...
more stuff.
$: sed -n '/<ItemGroup>/,/<[/]ItemGroup>/{ /<ItemGroup>/h;
/<[/]ItemGroup>/{ H; s/^.*//; x; /Test[.]bundle/{ s/^.*/cat new/e; }; p; d; }
H; d; }; p; ' old
stuff before
...
more stuff
<ItemGroup>
<BundleResource Include="Resourcessome_other_file.json" />
<BundleResource Include="ResourcesTest.bundlefour.png" />
<BundleResource Include="ResourcesTest.bundlefive.png" />
<BundleResource Include="ResourcesTest.bundlesix.png" />
<BundleResource Include="ResourcesTest.bundleseven.png" />
</ItemGroup>
stuff after
...
more stuff.
这显然对您的文件结构做了一些简单的假设。
awk
:中的相同逻辑
awk 'NR == FNR { new=new$0"n"; next; }
/<ItemGroup>/,/<[/]ItemGroup>/{ grp=grp$0"n";
if ($0 ~ "</ItemGroup>") { if (grp ~ "Test.bundle") { print new } else { print grp } grp="" } else next;
} 1' new old