首页 > 解决方案 > awk - 通过文件嵌套搜索?

问题描述

我有一个文件,其中列出了宏和其中使用的脚本元素。如果我知道脚本的名称,我已经能够逐行搜索文件并打印任何使用它的宏。那太棒了!非常感谢这里提供帮助的人。我现在遇到的问题是我想遍历文件,找到每个脚本并打印使用它的宏。我认为这可能是一个嵌套的 for 循环,首先找到每个脚本,然后测试每个宏,但还没有接近弄清楚。

这是脚本的实际示例行:

    SCR 4 0 RS1c80952b46129fc3bbf7b6d35e52f581d5d96edf "Custom: AUDIOBOOKS____ITEM_Select_on_selected_track_by_item_name____fill_1000ms.lua" /home/babag/Downloads/Reaper/ReaScripts/Scripts/BABAG/lua/AUDIOBOOKS____ITEM_Select_on_selected_track_by_item_name____fill_1000ms.lua

这些是使用上述脚本的两个实际宏行:

    MAC 1 0 "fad0ff7281777ae665363b96d96f1651" "Custom: AUDIOBOOKS____REPLACE_WITH_1000ms_ROOMTONE" _BR_SAVE_CURSOR_POS_SLOT_1 _SWS_SAVETIME1 _RSdebf6a0296631b3e9ce8c88c82d5d3da56e345de _RS1c80952b46129fc3bbf7b6d35e52f581d5d96edf 40698 _SWS_UNSELONTRACKS _SWS_RESTTIME1 _RSc48877ad5413b689c4abf510e70edfb7b138002c 40310 40718 _SWS_XFDOFF 40061 40630 40006 _SWS_AWPASTE _BR_RESTORE_CURSOR_POS_SLOT_1 40630 40635 40289 _SWS_HSCROLL50  
    MAC 1 0 "9d4aa8bac6f7cb3d76c673dd2639152b" "Custom: AUDIOBOOKS____PASTE_AT_CURSOR_wRIPPLE_1000ms_ROOMTONE" _BR_SAVE_CURSOR_POS_SLOT_1 _SWS_SAVETIME1 _RSdebf6a0296631b3e9ce8c88c82d5d3da56e345de _RS1c80952b46129fc3bbf7b6d35e52f581d5d96edf 40698 _SWS_UNSELONTRACKS _SWS_RESTTIME1 _RSc48877ad5413b689c4abf510e70edfb7b138002c 40310 40718 _SWS_XFDOFF _SWS_AWPASTE _BR_RESTORE_CURSOR_POS_SLOT_1 40289  

我用它来查找脚本行:

awk -v s='RS1c80952b46129fc3bbf7b6d35e52f581d5d96edf' '$1=="SCR"{for(i=4;i<=NF;i++) if($i==s) {print $6; next}}' inputfile.txt

我用它来查找宏行:

awk -v s='_RS1c80952b46129fc3bbf7b6d35e52f581d5d96edf' '$1=="MAC"{for(i=7;i<=NF;i++) if($i==s) {print $6; next}}' inputfile.txt

我完全不知道如何将这些结合起来并让它们相互交谈以列出每个脚本及其出现的宏。输出类似于:

scriptname1 is used in the following macros:  
macroname  
macroname  
macroname

scriptname2 is used in the following macros:  
macroname  
macroname  
macroname  

scriptname3 is used in the following macros:  
macroname  
macroname  
macroname  

标签: awk

解决方案


在这种情况下,您需要对文件进行两次解析:一次是收集脚本,一次是检查宏。

awk '
    NR == FNR {
        if ($1 == "SCR") script["_"$4] = $6
        next
    }
    $1 == "MAC" {
        for (i=7; i<=NF; i++)
            if ($i in script)
                script_uses[$i] = script_uses[$i] $6 ORS
    }
    END {
        for (id in script_uses)
            printf "%s is used in macros:\n%s\n", script[id], script_uses[id]
    }
' file file

如果文件包含:

MAC 1 0 12345 x MACRO1  _foo _bar _567 _baz _987 _qux
SCR 4 0 567   x SCRIPT1 /path/to/script1
MAC 1 0 2354  x MACRO2  _abc _987 _def _ghi
SCR 4 0 987   x SCRIPT2 /path/to/script2

然后输出是

SCRIPT2 is used in macros:
MACRO1
MACRO2

SCRIPT1 is used in macros:
MACRO1

推荐阅读