使用awk操纵来自两个来源的数据

时间:2019-05-14 14:38:57

标签: bash awk

作为我团队中CI \ CD流程的一部分,我想从包含一些资源路径的文件中生成动态命令脚本。

文件path.txt包含路径,以新行分隔。对于此文件中的每一行,都应生成一条命令,除非该命令以“ JarPath / ...”开头

示例:

JarPath/DontTouchMe.jar
path/to/some/resource/View/PutMeInScript.msgflow
path/to/some/resource/Control/MeAlso.map

mapping.txt文件包含一个键值对。关键字是与paths.txt中的路径匹配的短语,并且它的值对于生成的命令是必需的。

示例:

View viewEG.bar
Control controlEG.bar

path.txt中的行未排序,某些路径可以匹配mapping.txt中的单个值。
仅应考虑mapping.txt文件中与路径中第一个可能的分析相匹配的第一个匹配项。我不在乎映射中的后面的行是否也匹配,或者路径中的后面的目录是否也匹配其他行。
路径中要匹配的解析不在固定位置(例如,第4个“ /”之后)

脚本文件中的最终结果应为:

mqsicreatebar -data ./ -b viewEG.bar -o /path/to/some/resource/View/PutMeInScript.msgflow
mqsicreatebar -data ./ -b controlEG.bar -o /path/to/some/resource/Control/MeAlso.map

由于命令行从两个来源(paths.txt和mapping.txt中的一个值对)获取数据,因此我无法将其包装为单个awk命令,也无法将其通过管道传输至单个bash行。我写道:

pathVar="paths.txt"
touch deltaFile.txt
while IFS= read -r line
do
  awk -v var=$line" 'var ~ $1 && var !~ /^JarPath/ {print $2, " ", var ;exit}' mapping.txt >>  deltaFile.txt
done < "$pathVar"
IFS=$'\n'
awk '{print "mqsicreatebar -data ./ -b", $1, "-o", $2 }' deltaFile.txt > script.sh

嗯,它可行,但是有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

请在下面的评论中Only the first match in the mapping.txt file that matches the first possible parse in the path should be considered. The key dir can appear anywhere,这就是您所需要的:

$ cat tst.awk
NR==FNR {
    keys[++numKeys] = $1
    map[$1] = $2
    next
}
!/^JarPath/ {
    numDirs = split($0,dirs,"/")
    val = ""
    for (dirNr=1; (dirNr<=numDirs) && (val==""); dirNr++) {
        dir = dirs[dirNr]
        for (keyNr=1; (keyNr<=numKeys) && (val==""); keyNr++) {
            key = keys[keyNr]
            if (dir == key) {
                val = map[dir]
            }
        }
    }
    printf "mqsicreatebar -data ./ -b \047%s\047 -o \047%s\047\n", val, $0
}

$ awk -f tst.awk mapping.txt paths.txt
mqsicreatebar -data ./ -b 'viewEG.bar' -o 'path/to/some/resource/View/PutMeInScript.msgflow'
mqsicreatebar -data ./ -b 'controlEG.bar' -o 'path/to/some/resource/Control/MeAlso.map'