0

我有多个带有某种规则库的 CSV,我需要从中解析和创建命令,但我遇到了多个问题。

在开始之前,这里有一个布局示例,以及它的外观:

$1 = Rule number
$3 = Source
$4 = Destination
$5 = Service
$6 = Action
$7 = Track
$10 = Comments

.

Security Policy: Blahblahblah,,,,,,,,,
12,,host_A,net-B,https,drop,Log,Any,Any,comments
13,,host_A,net-B,smtp,drop,Log,Any,Any,comments
14,,host_A,net-B,http,accept,Log,Any,Any,comments 
,,net-C,,,,,,,
,,net-D,,,,,,,
15,,host_A,net-B,http,accept,Log,Any,Any,comments
,,host_B,net-C,service_X,,,,,
,,host_C,net-D,service_y,,,,,
,,host_D,,,,,,,
,,host_E,,,,,,,

问题 1:需要在循环内调整第 1 列(规则编号)。我需要从中减去一个变量以等于正确的数字(需要移位)。例如,第一条规则#12,需要在循环中成为#1。

我用它来创建我需要从每个连续行的原始变量中减去的变量(取第一行,减去一个):

`awk -F, 'NR==2 {print $1 -1 }'

问题 #2:我需要在 Rule# 的每个实例上迭代这个循环。IE:每个规则“可以”有多个来源/目的地/服务,我需要能够将新对象与正确的规则联系起来。

还需要检查 $1 的错误,因为有一些字段/规则需要跳过,它们以“禁用”或类似的东西开头。这似乎可以解决问题:

awk -F, '$1 ~ "^[0-9]*$" {print $1}

总的来说,我希望最终输出如下所示:

(所有 echo'd/awk print'd 等):

if new rule # is found in $1:
create rule security_rule
create action $rule_number $action
create comment $rule_number $comment
create source $rule_number $source <--- iterate as many times as required
create destination $rule_number $destination <--- iterate as many times as required
create service $rule_number $service <--- iterate as many times as required
create track $rule_number $track

ETC...

您可以提供的任何帮助/建议将不胜感激。

谢谢,

编辑:一个更好的例子(规则 1 = CSV 中的规则 12 - 这些仍然是粗略的打印语句,我可以稍后填写正确的打印值):

if new rule # is found in $1:
create rule security_rule
create action rule 1 drop
create comment rule 1 "This is a comment"
create source rule 1 host_A
create destination rule 1 net-B
create service rule 1 https
create track rule 1 Log

具有多个源/目标/服务的那些将简单地添加额外的“创建源规则 x”行,如下所示:

if new rule # is found in $1:
create rule security_rule
create action rule 3 accept
create comment rule 3 "This is a comment"
create source rule 3 host_A
create source rule 3 net-C
create source rule 3 net-D
create destination rule 3 net-B
create service rule 3 http
create track rule 3 Log
4

2 回答 2

1

awk 可以做到这一点,但它有点笨拙。您基本上将信息收集在一个大字符串中,然后在完成每个字符串后将其打印出来。(只记得打印最后一个)

我省略了if new rule # is found in $1:一点......因为我不完全理解它应该如何工作。如果您绝对需要“跟踪”行显示在末尾...只需将 $3、$4 和 $5 的行复制为 $7。

BEGIN{
    FS=",";recNum=0;curLine=""
}

$1 ~ /^Security Policy/ {next}

$1!="" {
    print curLine,"\n"
    recNum++;
    $1=recNum;
    curLine=sprintf("create rule security_rule\ncreate action rule %d %s\n",$1,$6);
    curLine=curLine sprintf("create comment rule %d \"%s\"\n",$1,$10);
    curLine=curLine sprintf("create track rule %d %s\n",$1,$7);
}
$1=="" {
    $1=recNum;
}

$3!=""{
    curLine=curLine sprintf("create source rule %d %s\n",$1,$3);
}
$4!=""{
    curLine=curLine sprintf("create destination rule %d %s\n",$1,$4);
}
$5!=""{
    curLine=curLine sprintf("create service rule %d %s\n",$1,$5);
}
END {print curLine}

对于您上面的输入,这给了我:

create rule security_rule
create action rule 1 drop
create comment rule 1 "comments"
create track rule 1 Log
create source rule 1 host_A
create destination rule 1 net-B
create service rule 1 https


create rule security_rule
create action rule 2 drop
create comment rule 2 "comments"
create track rule 2 Log
create source rule 2 host_A
create destination rule 2 net-B
create service rule 2 smtp


create rule security_rule
create action rule 3 accept
create comment rule 3 "comments"
create track rule 3 Log
create source rule 3 host_A
create destination rule 3 net-B
create service rule 3 http
create source rule 3 net-C
create source rule 3 net-D


create rule security_rule
create action rule 4 accept
create comment rule 4 "comments"
create track rule 4 Log
create source rule 4 host_A
create destination rule 4 net-B
create service rule 4 http
create source rule 4 host_B
create destination rule 4 net-C
create service rule 4 service_X
create source rule 4 host_C
create destination rule 4 net-D
create service rule 4 service_y
create source rule 4 host_D
create source rule 4 host_E
于 2013-04-03T16:38:03.860 回答
0

我对这个问题并不完全清楚,但正如@Charles Duffy 所提到的,为什么不使用本机bash,你能否提供一个示例文件及其输出,我试图从你的问题中分解要求,但迷路了。无论如何,下面是一个小例子,您可以尝试修改以适应您的要求,同样可以通过 awk 完成,这将更优雅(恐怕我在 awk 中没有那么多),我强行将第一列设置为数组索引,将第三个值保留为“hello”,如果为空则保留旧值。

[bash]$ cat example;echo "##################################################"; ./tmp.sh < example ;echo "##################################################"; cat tmp.sh
12,,host_A,net-B,https,drop,Log,Any,Any,comments
13,,host_A,net-B,smtp,drop,Log,Any,Any,comments
14,,host_A,net-B,http,accept,Log,Any,Any,comments
,,net-C,,,,,,,
,,net-D,,,,,,,
15,,host_A,net-B,http,accept,Log,Any,Any,comments
,,host_B,net-C,service_X,,,,,
,,host_C,net-D,service_y,,,,,
,,host_D,,,,,,,
,,host_E,,,,,,,
##################################################
0 host_A hello https drop Log Any Any comments
1 host_A hello smtp drop Log Any Any comments
2 host_A hello http accept Log Any Any comments
3 net-C hello http accept Log Any Any comments
4 net-D hello http accept Log Any Any comments
5 host_A hello http accept Log Any Any comments
6 host_B hello service_X accept Log Any Any comments
7 host_C hello service_y accept Log Any Any comments
8 host_D hello service_y accept Log Any Any comments
9 host_E hello service_y accept Log Any Any comments
##################################################
#!/bin/bash
oldarr=();
oldarr[3]="hello"
index=0
while IFS=',' read -ra newarray
#do any rule which is iteration over data
do
  for (( i = 0; i < ${#newarray[@]}; i++))
  do
    if [ "${newarray[$i]}" ]
    then
#put any exceptional case
      if [ "$i" != "3" ]
      then
      oldarr[$i]=${newarray[$i]}
      fi
    fi
  done
#put anything which is independent of iteration
  oldarr[0]=$index
  ((index++))
  echo ${oldarr[*]}
done
于 2013-04-03T18:22:28.930 回答