从文件中查找定义的数据并用作变量

时间:2019-02-27 10:57:51

标签: linux bash loops curl

我对多个创建配置文件有一些POST卷曲请求。下一步,我发送GET请求以获取所有创建的配置文件并将结果保存到* .txt文件。然后,我想在此文件中仅找到具有 ID 的数据,并使用它对所有配置文件进行多次更新(通过PUT请求)或多次删除。

#!/bin/bash
token="Authorization: Bearer 1bcXamxE5sSpT8A-7L_fJIWA"
url="http://ad44fcfa01aad11e9naws.com/api/v0.1/scanprofiles"
curl -X GET $url -H 'Content-Type: application/json' -H "$token" > get.txt

q=15

name=3_Ubuntu_internal

ports=1042

h=12
m=41
for ((i = 0; i < q; i++))
 do
    data='{"target":{"scan_type":"internal","ip_range":"10.142.0.2-10.142.0.5","ports":"'${ports}'"},"name":"'$name$i'","run_immediately":"False", "schedule": {"utc_offset": 120, "time": "'${h}':'${m}'",  "start_date": "2019-02-26T10:13:00+02:00","recurrence":{"recurrence_type": "daily","data":{"spike":"1"}}}}'
    ports=$((ports+1))
    m=$((m+1))
    if [ "${m}" -eq "60" ];
      then 
      h=$((${h}+1)) && m=41
    fi
    if [ "${h}" -eq "15" ];
      then 
      h=12
    fi
    if [ "${ports}" -eq "1238" ];
     then
     ports=1042
    fi

    echo "${data}"
    curl -X POST $url -H 'Content-Type: application/json' -H "$token" -d "$data"
 done   

简单的GET请求答案:

{
        "status": "ready",
        "last_run_time": "2019-02-27T10:44:34+00:00",
        "found_cert_count": 3,
        "id": "0a3c62a9-2f61-4e78-802a-2a6b31e43af8",
        "tenant_id": "840ccfeb-ee3b-451f-aaf9-7a4fe8f3cbee",
        "target": {
            "ip_range": "10.142.0.2-10.142.0.5",
            "scan_type": "internal",
            "ports": "1045"
        },
        "name": "3_Ubuntu_internal3",
        "scan_run_id": "be263639-cbaa-44e5-a249-f2c38f12c80f",
        "run_immediately": "False",
        "schedule": {
            "utc_offset": 120,
            "time": "12:41",
            "start_date": "2019-02-26T08:13:00+00:00",
            "recurrence": {
                "recurrence_type": "daily",
                "data": {}
            }
        },
        "next_run_time_utc": "2019-02-28T10:41:00+00:00"

因此,我需要获取所有“ id” :“ 0a3c62a9-2f61-4e78-802a-2a6b31e43af8 ”,并在下一个PUT上使用它(仅GUID)或在循环中删除请求

最后的工作代码是:

  #!/bin/bash
token="Authorization: Bearer XVbusTNtmjAYFoAJQ"
url="http://us-east-1.elb.amazonaws.com/api/v0.1/profiles/"
url_run="http://us-east-1.elb.amazonaws.com/api/v0.1/profiles/run"
local="http://localhost:62183/api/v0.1/profiles/"
local_run="http://localhost:62183/api/v0.1/profiles/run"
q=10
name=New_UbuntuX
host=(15.11.38.43 15.11.49.89 15.11.188.24 15.11.19.83 15.20.155.82 15.20.14.27 15.11.14.31 15.11.14.23 15.11.19.17 15.11.29.47)
data1=""
curl -X GET $url -H 'Content-Type: application/json' -H "$token" > get.txt
id=($(sed -En '/"id"\s*:/ { s/.*"id"\s*:\s*"([^"]+)".*/\1/; p; }' get.txt)) 
printf "%s\n" "${id[@]}"
#next request should be delete all found profiles by id
for i in "${id[@]}"#I know that seems not properly correct just paste it to 
#show how I'm think that should be in there
  do
   curl -X DELETE $url"${id[@]}" -H "Content-Type: application/json" 
  done
"$token"
for ((i = 0; i < q; i++))
 do
    data='{"target": 
 {"scan_type":"external","host":"'${host[$i]}'","ports":"143- 
 184"},"name":"'$name$i'","run_immediately":"False"}'
    curl -X POST $url -H 'Content-Type: application/json' -H "$token" -d 
"$data" #create external profiles with defined host
 done
 curl -X PUT -H "Content-Type: application/json" $url_run -H "$token" -d 
"$data1" #run all profiles

1 个答案:

答案 0 :(得分:1)

同样,我推荐一个真正的JSON解析器,但是-
首先,道歉。我的复制/粘贴已损坏。它具有嵌入的^ C中断,并且没有尾随括号或引号。
我的罪魁祸首。

打破现状:

id=$( sed -En '/"id"\s*:/ { s/.*"id"\s*:\s*"([^"]+)".*/\1/; p; }' get.txt )

id=是标准变量分配。
$( ... )运行其内容并返回stdout,此处将在id=$( ... )构造中分配该值。

让我们看一下sed

-E使用扩展模式匹配,因此(例如)我不需要反斜杠使它们成为元字符。
-n说除非我明确要求,否则不要打印任何东西。

程序:

/"id"\s*:/ { ... }表示当行与斜杠之间的模式匹配时,执行括号之间的命令。
模式是文字"id",后跟任意数量(0或更多)的空格字符(\s*),后跟冒号。

s/.*"id"\s*:\s*"([^"]+)".*/\1/; p;是要在匹配行上运行的命令列表。
替换为s/<find>/<replace>/;
在这种情况下,是.*"id"\s*:\s*"([^"]+).*;坏了, .*匹配任意数量的“ any”字符。有关详细信息,请参见手册。这将丢弃我们关心的部分之前的所有内容。 "id"\s*:\s*"表示要找到"id",零个或多个空格,冒号,另一个零个或多个空格,后跟双引号字符 ([^"]+)是重要的部分-家长说要记住它们之间的内容; [^"]+表示一个或多个非双引号字符。 ".*会丢弃数据末尾的引号以及该数据后的任何/所有尾随字符。

这时,匹配的数据应为"id":所标识的引号之间的值,并应存储在\1中。
该部分是\1,因此应将整行剪裁为所需的部分。

p;说要打印现在已修剪的行,因此id应该存储在变量中。

请确保您的数据中符合这些条件的ID不超过一个。...

  

编辑

将它们放入数组中。重复了几次。

$: id=( $( sed -En '/"id"\s*:/ { s/.*"id"\s*:\s*"([^"]+)".*/\1/; p; }' get.txt ) )
$: printf "[%s]\n" "${id[@]}"
[first-0a3c62a9-2f61-4e78-802a-2a6b31e43af8]
[second-0a3c62a9-2f61-4e78-802a-2a6b31e43af8]
[3rd-0a3c62a9-2f61-4e78-802a-2a6b31e43af8]
[4th-0a3c62a9-2f61-4e78-802a-2a6b31e43af8]
[5th-0a3c62a9-2f61-4e78-802a-2a6b31e43af8]
[last-0a3c62a9-2f61-4e78-802a-2a6b31e43af8]
  

下一步编辑

c.f。:

for i in "${id[@]}"
do  curl -X DELETE $url"${id[@]}" -H "Content-Type: application/json" 
done
"$token"

首先,您是否在"$token"遇到错误?
可能应该说的是模糊的话

bash: Authorization:: command not found

第二个-for i in "${id[@]}"依次为每个i设置id,但是您再也不会在循环中使用它了。相反,您使用

curl -X DELETE $url"${id[@]}" -H "Content-Type: application/json" 

这不会做你想要的。

看这个例子:

$: x=( a b c )
$: for i in "${x[@]}"
>  do echo "Right:  id is '$i'"
>     echo "Wrong:  id is '${x[@]}'"
> done
Right:  id is 'a'
Wrong:  id is 'a b c'
Right:  id is 'b'
Wrong:  id is 'a b c'
Right:  id is 'c'
Wrong:  id is 'a b c'

您做的是错误的。尝试这种方式:

for i in "${id[@]}"
do  curl -X DELETE "$url$i" -H "Content-Type: application/json" 
done

不过,直到您获得正确的授权,这仍然不太可能起作用,所以...

declare -a stdArgs=( -H "Content-Type: application/json" -H "$token" ) 
for i in "${id[@]}"
do  curl -X DELETE "$url$i" "${stdAtrgs[@]}"
done

看看是否更好。