我对多个创建配置文件有一些 POST curl 请求。下一步,我发送 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 或 DELETE 请求中使用它(仅 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
最佳答案
我再次推荐一个真正的 JSON 解析器,但是 -
首先,道歉。我的复制/粘贴已损坏。它有一个嵌入的 ^C-break,并且没有尾随括号或引号。
我承认错误。
分解:
id=$( sed -En '/"id"\s*:/ { s/.*"id"\s*:\s*"([^"]+)".*/\1/; p; }' get.txt )
id=
是标准变量赋值。
$( ... )
运行它的内容并返回标准输出,这里将在 id=$( ... )
中分配它构造。
让我们看看 sed
.
-E
使用扩展模式匹配,因此(例如)我不需要反斜杠括号来使它们成为元字符。
-n
说除非我明确要求,否则不要打印任何内容。
程序:
/"id"\s*:/ { ... }
表示当该行与斜杠之间的模式匹配时执行大括号之间的命令。
该模式是一个文字 "id"
后跟任意数量(0 或更多)的空白字符 ( \s*
),后跟冒号。
s/.*"id"\s*:\s*"([^"]+)".*/\1/; p;
是在匹配行上运行的命令列表。
替换为s/<find>/<replace>/;
在这种情况下,是 .*"id"\s*:\s*"([^"]+).*
; splinter ,
.*
匹配任意数量的“任意”字符。详细信息请参阅手册。这会丢弃我们关心的部分之前的所有内容。
"id"\s*:\s*"
说找到"id"
、零个或多个空格、一个冒号、另一个零个或多个空格、后跟一个双引号字符
([^"]+)
是重要的部分 - parent 说要记住他们之间的事情; [^"]+
表示一个或多个非双引号字符。
".*
丢弃数据末尾的引号及其后面的任何/所有尾随字符。
此时,匹配的数据应该是 "id":
标识的引号之间的值。 ,并且应该存储在 \1
中.
该部分是\1
,所以整条线应该被修剪成你想要的部分。
p;
说要打印现在修剪的行,因此 id 应该存储在变量中。
确保您的数据中不存在多个符合这些条件的 ID...
EDIT
将它们放入一个数组中。重复了几次该行。
$: 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]
Next Edit
参照:
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
看看这样是否更好。
关于linux - 从文件中查找定义的数据并用作变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54903881/