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

标签 linux bash loops curl

我对多个创建配置文件有一些 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/

相关文章:

linux - awk 计数模式匹配并对它们之后的数字求和

php - 如何限制进程使用(用户或进程)

linux - 如果java进程死于脚本,如何启动它

javascript - JavaScript 中的无限循环不会触发浏览器警告

java - 对于 Java 中特定实例的每个对象循环

ruby - 我无法在 Ubuntu 14 中安装 ShoesRB。问题是 .run 或 .install 文件类型吗?

linux - 列表命令不显示所有输出

json - 使用jq将多个JSON的一个属性连接到一个文件中

arrays - 如何在数组中存储带有空格的元素?

arrays - MIPS中的冒泡排序算法