![Sed:删除所有与模式匹配的内容](https://linux22.com/image/1235720/Sed%EF%BC%9A%E5%88%A0%E9%99%A4%E6%89%80%E6%9C%89%E4%B8%8E%E6%A8%A1%E5%BC%8F%E5%8C%B9%E9%85%8D%E7%9A%84%E5%86%85%E5%AE%B9.png)
我在 Mac OS X 上有一些 plist 文件,我想将它们压缩。它们有很多<dict>
带有<key>
和值的内容。其中一个键是缩略图,其<data>
值带有 base64 编码的二进制文件(我认为)。我想删除这个键和值。
我在想这也许可以通过 sed 来完成,但我真的不知道如何使用它,而且 sed 似乎只能逐行工作?
不管怎样,我希望有人能帮助我。我想删除文件中与以下模式匹配或接近该模式的所有内容:
<key>Thumbnail<\/key>[^<]*<\/data>
在文件中它看起来像这样:
// Other keys and values
<key>Thumbnail</key>
<data>
TU0AKgAAOEi25Pqx3/ip2fak0vOdzPCVxu2RweuPv+mLu+mIt+aGtuaEtOSB
...
dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
</data>
// Other keys and values
有人知道我该怎么做吗?另外,如果有更好的工具可以在终端中用来做这件事,我也想知道 :)
答案1
命令行上有两个专用于处理首选项列表文件的实用程序:defaults
(in /usr/bin
) 和PlistBuddy
in ( /usr/libexec
)。
仍在使用sed
:
sed
D
确实允许使用而不是标志来删除多行d
。
例如sed -e '/<key>Thumbnail<\/key>/, /<\/data>/D' < /PATH/TO/FILE.txt
删除关键缩略图的所有实例及其相关数据。
使用defaults
:
defaults delete /PATH/TO/PLIST "Thumbnail"
。请勿将.plist
扩展名作为路径的一部分。此外,这仅适用于 中的根级项目.plist
,因此如果 Thumbnail 键位于另一个数组或字典中,它将不起作用。
使用PlistBuddy
:
/usr/libexec/PlistBuddy -c "Delete :Thumbnail" /PATH/TO/PLIST.plist
。如果缩略图键是嵌套的,您可以在其前面附加路径(如果您知道的话)。例如,PlistBuddy -c "Delete :User:Thumbnail"
如果缩略图条目位于用户词典中。
答案2
XMLStarlet是一款非常棒的用于操作 XML 的命令行工具。它的主要问题是 1) 它是一个非常复杂的工具(因为它可以做非常复杂的工作),2)你可能必须自己为 OS X 构建它。
答案3
使用 awk,而不是 sed
$ cat file
asdkf
asdklf
// Other keys and values
<key>Thumbnail</key>
<data>
TU0AKgAAOEi25Pqx3/ip2fak0vOdzPCVxu2RweuPv+mLu+mIt+aGtuaEtOSB
...
dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
</data>
// Other keys and values
ksdf
$ awk 'BEGIN{RS="</data>"} /<key>/{ gsub("<key>.*</key>|<data>.*","") }1' file
asdkf
asdklf
// Other keys and values
// Other keys and values
ksdf
该语句表示,用作</data>
记录分隔符,然后替换标签<key>
,并<data>
用空值替换,当<key>
在记录中找到时
答案4
也许可以使用 sed 来实现这一点,但会比较困难。Perl 可以更轻松地实现这一点。perl 脚本的核心内容如下:
undef $/; # This allows reading in of all lines in one swoop
$contents = <>; # Read in contents of file (specified on command line)
$contents = s{<key>Thumbnail</key>.*?</data>}{}s;
print $contents;
如果您在名为 change.plx 的 perl 脚本中有上述内容,并且您的数据在名为 keyfile 的文件中,那么您可以通过执行以下操作来修复该文件:
$ perl change.plx keyfile > /tmp/$$ && cat /tmp/$$ > keyfile && rm /tmp/$$
当然,请确保对执行此操作的任何文件都进行了备份。可以使用命令行上的单个单行 perl 程序对多个文件进行所有这些工作,如下所示:
$ perl -p0777i -e 's{<key>Thumbnail</key>.*?</data>}{}s;' file file file ...
马尼克斯