【问题标题】:Using sed or awk to parse current field/column into additional fields/columns on the same line使用 sed 或 awk 将当前字段/列解析为同一行上的其他字段/列
【发布时间】:2012-11-14 17:19:09
【问题描述】:

这里是感兴趣的文本文件的 4 行示例

EnumerateKey,explorer.exe,HKCR\\Directory\\shellex\\ContextMenuHandlers,NOMORE
CreateSec,explorer.exe,\\WINDOWS\\system32\\verclsid.exe,SUCCESS
QueryKey,AcroRd32.exe,HKCU\\Control Panel\\International,BUFOVRFLOW       
QueryValue,AcroRd32.exe,HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\NoRecentDocsHistory,NOTFOUND

我想通过附加 K 个字段/列(例如下面的 K=3)来增加行,这些字段/列包含在 $3 中找到但由 \\ 解析的路径的元素

这是 4 行所需的输出。

EnumerateKey,explorer.exe,HKCR\\Directory\\shellex\\ContextMenuHandlers,NOMORE, Directory, shellex, ContextMenuHandlers
CreateSec,explorer.exe,\\WINDOWS\\system32\\verclsid.exe,SUCCESS, WINDOWS, system32, verclsid.exe
QueryKey,AcroRd32.exe,HKCU\\Control Panel\\International,BUFOVRFLOW, Control Panel, International,
QueryValue,AcroRd32.exe,HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\NoRecentDocsHistory,NOTFOUND, Software, Microsoft, Windows

经过进一步研究,这里有 2 个细微差别:

有些路径以 HK** 开头,有些则不是。但是,在这两种情况下,我只关心在初始 \\ 之后开始的路径。在第 1 行和第 2 行之间捕获了这种差异。因此,我认为解析必须锚定在 \\ 而不是简单的 $3 如果可能的话。 (我是否正确使用了该术语?)

其次,路径的深度不同。为了保持列/字段的一致性,我愿意丢失一些信息(第 4 行)以及为短路径(第 3 行)留出空白字段以保持这一点。

【问题讨论】:

    标签: parsing sed awk


    【解决方案1】:

    这是使用GNU awk的一种方式:

    awk 'BEGIN { FS=OFS="," } { split($3,a,"\\\\\\\\"); print $0, a[2], a[3], a[4] }' file
    

    结果:

    EnumerateKey,explorer.exe,HKCR\\Directory\\shellex\\ContextMenuHandlers,NOMORE,Directory,shellex,ContextMenuHandlers
    CreateSec,explorer.exe,\\WINDOWS\\system32\\verclsid.exe,SUCCESS,WINDOWS,system32,verclsid.exe
    QueryKey,AcroRd32.exe,HKCU\\Control Panel\\International,BUFOVRFLOW,Control Panel,International,
    QueryValue,AcroRd32.exe,HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\NoRecentDocsHistory,NOTFOUND,Software,Microsoft,Windows
    

    【讨论】:

    • 如果在每个拆分字段后需要空格,您可以将开始块更改为:BEGIN { FS=","; OFS=", " }。顺便说一句,您的预期输出有点不一致。
    • 谢谢!对于接下来的那些,您可以扩展 a[i] 格式以更改 K,如问题描述中所述。
    • 我已经在问题描述中编辑了我想要的输出,以消除提到的不一致。
    【解决方案2】:

    使用一些丑陋的 Perl:

    perl -lane '{$l=$_;s/.*?\\\\([^,]*),.*/$1/;@v=split(/\\\\/,$_); print "$l,".join(",",@v[0,1,2]);}' input
    

    【讨论】:

      猜你喜欢
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多