从fs_usage的输出中提取路径

时间:2015-07-17 17:25:39

标签: regex macos sed

我在RegExp和sed上有点生疏(同时Mac版本与GNU的差异对我的尝试没有帮助)经过相当多的尝试[几个小时],我还没有完成解析这样的输入:

16:32:07.961689  stat64                                 /System/Library/Frameworks/CoreBluetooth.framework/Versions/A/CoreBluetooth                                                                                           0.000007   JavaApplicationS.65394
16:32:07.961742  stat64                                 /System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols                                                                                      0.000006   JavaApplicationS.65394
16:32:07.961764  stat64                                 /System/Library/PrivateFrameworks/CoreSymbolication.framework/Versions/A/CoreSymbolication                                                                            0.000007   JavaApplicationS.65394
16:32:07.961785  stat64                                 /System/Library/PrivateFrameworks/Symbolication.framework/Versions/A/Symbolication                                                                                    0.000007   JavaApplicationS.65394
16:32:07.961830  stat64                                 /System/Library/PrivateFrameworks/SpeechRecognitionCore.framework/Versions/A/SpeechRecognitionCore                                                                    0.000008   JavaApplicationS.65394
16:32:07.962321  open              F=3        (RW____)  /dev/dtracehelper                                                                                                                                                     0.000061   JavaApplicationS.65394
16:32:07.968239  stat64                 [  2]           /AppleInternal>>>>>>>>>>

仅提取路径。请注意,列数会有所不同,我想我想要的是附加到/字符的任何内容,它都被空格包围。此外,有时几条路径出现在同一条线上,例如

16:32:06.706726    WrData[A]       D=0x13589148  B=0x100000 /dev/disk0s2  /private/var/folders/92/663yx9fn2036kz6pb3kr8z0r0000gp/0/com.apple.LaunchServices-107502.csstore~ 

在这些情况下,它们都很棒:输出/ dev / disk0s2和/ private ..或只需 / private ..也没关系。

因此,基本上所有写入或读取的文件都是由Mac OS X fs_usage工具报告的。解决方案不必基于sed,我也可以为此编写一些代码,但在我这样做之前,我只想知道是否有更容易的'方式。

谢谢!

3 个答案:

答案 0 :(得分:2)

尝试使用egrep,它可以处理正则表达式:

egrep -o '/[^ >]*' file

<强>结果:

/System/Library/Frameworks/CoreBluetooth.framework/Versions/A/
...

答案 1 :(得分:0)

如果你可以使用PCRE / Perl,你可以使用带有可选组的长正则表达式从这种类型的日志中提取数据。

这是我提出的一个:

_user = new USER();
_user.Username = user.Username

DbContext.USERS.Add(_user);
DbContext.SaveChanges();

var newUser = DbContext.USERS.Find(_user.User_Id);                                               

foreach (int assocId in select2)
{
LNK_UserRoleAssoc u = new LNK_UserRoleAssoc();                           
u.User = newUser;
u.Association = DbContext.Associations.Find(assocId);
u.Role = DbContext.ROLES.Find(2);
newUser.UserRoleAssocs.Add(u);                          
}

DbContext.SaveChanges();

请参阅demo

答案 2 :(得分:0)

注意事项:即使使用 fs_usage 运行,-w 也会截断长路径(从头开始,而不是在最后),因此它们不会全部以 / 开头。
我发现这个线程有同样的问题要解决,我详细说明了 egrep 解决方案:
cut -c 57-222 file.txt | egrep -o '[^ ].*/[^>]+[^ ]'
这似乎也适用于截断的(但不要相信我的话)。

说明:cut 提取路径实际所在的列,然后 egrep 粗略地提取其中至少包含一个 / 的字符串(也允许路径名中有空格)。

TBH 我不确定我的解决方案是否 100% 正确(可能不是)。

顺便说一句,除了被截断的应用程序之外,我还得到了不以 / 开头的路径,这些路径与应用程序包内的某个位置相关。
示例(使用 Xcode 7.3.1 作为测试对象):
A/Resources/XCWelcome-NewCheckoutTemplate.pdf 实际上是 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/XCWelcome-NewCheckoutTemplate.pdf
截断路径示例:ations/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/Library/GPUTools/PlugIns/GLToolsMobileAnalysis.gtplugin/Contents/Resources/PlugIn.plist

注意:fs_usage sources 确认截断。我还没有尝试过,但从理论上讲,如果真的有必要,可以重新定义宽度的宽度(寻找 MAX_WIDE_MODE_COLS)。以防万一,我建议不要管系统命令,并在重要的时候保留一个重命名的“超大”版本。