Bash 脚本反向引用

Bash script back reference

尝试通过以下示例文件中的 bash shell 模式匹配仅提取 62f0fac3-8b19-49de-866b-5f5cf23f2f9f 和 bd23d38d-8833-4fc4-b6c0-3906df0ed161。该文件包含单行文本,其中出现了许多此类模式。

尝试了 grep 和 sed 的反向引用。 none 似乎有效。非常感谢任何帮助。

"type": "Primary", "id": "418bf692-4f20-4597-b624-5a7242b82379", "expireIn": {"count": 0, "unit": "hours"}}], "copyModel": "ARCHIVE", "id": "6f2d6bc6-f67c-41b8-b11a-b5a59d7a6ac3"}], "id": "62f0fac3-8b19-49de-866b-5f5cf23f2f9f", "createdAt": "2020-08-11T17:33:45.754863Z", "name": "Susanta Copy Policy"}, "locked": false, "type": "Primary", "id": "ca85d285-8b73-42ec-aab1-c4d13572db94", "expireIn": {"count": 61, "unit": "days"}}], "advancedOptions": {"targetConnectivity": "Auto"}, "id": "f61e67a4-eea6-4922-9cc1-491a5429b199"}], "id": "bd23d38d-8833-4fc4-b6c0-3906df0ed161", "createdAt": "2020-07-14T19:01:33.202434Z", "name": "App Gold Policy"}, "locked": false
#
#
# cat test | grep -E '\"id\": \"(.*)\", \"createdAt\": \"'
"type": "Primary", "id": "418bf692-4f20-4597-b624-5a7242b82379", "expireIn": {"count": 0, "unit": "hours"}}], "copyModel": "ARCHIVE", "id": "6f2d6bc6-f67c-41b8-b11a-b5a59d7a6ac3"}], "id": "62f0fac3-8b19-49de-866b-5f5cf23f2f9f", "createdAt": "2020-08-11T17:33:45.754863Z", "name": "Susanta Copy Policy"}, "locked": false, "type": "Primary", "id": "ca85d285-8b73-42ec-aab1-c4d13572db94", "expireIn": {"count": 61, "unit": "days"}}], "advancedOptions": {"targetConnectivity": "Auto"}, "id": "f61e67a4-eea6-4922-9cc1-491a5429b199"}], "id": "bd23d38d-8833-4fc4-b6c0-3906df0ed161", "createdAt": "2020-07-14T19:01:33.202434Z", "name": "App Gold Policy"}, "locked": false
#
# cat test | grep -E '\"id\": \"(.*)\", \"createdAt\": \"'
#
# cat test | sed -E 's/\"id\"(.*)\"\, \"createdAt\": \"//'
"type": "Primary", : "418bf692-4f20-4597-b624-5a7242b82379", "expireIn": {"count": 0, "unit": "hours"}}], "copyModel": "ARCHIVE", "id": "6f2d6bc6-f67c-41b8-b11a-b5a59d7a6ac3"}], "id": "62f0fac3-8b19-49de-866b-5f5cf23f2f9f", "createdAt": "2020-08-11T17:33:45.754863Z", "name": "Susanta Copy Policy"}, "locked": false, "type": "Primary", "id": "ca85d285-8b73-42ec-aab1-c4d13572db94", "expireIn": {"count": 61, "unit": "days"}}], "advancedOptions": {"targetConnectivity": "Auto"}, "id": "f61e67a4-eea6-4922-9cc1-491a5429b199"}], "id": "bd23d38d-8833-4fc4-b6c0-3906df0ed1612020-07-14T19:01:33.202434Z", "name": "App Gold Policy"}, "locked": false
#```

为了与 grep 一起使用,您需要针对 Perl 语法的选项 -P。选项 -o 将只打印匹配行的匹配 (non-empty) 部分,每个这样的部分在单独的输出行上。

然后您可以进行否定前瞻和 non-greedy 匹配(这里已经很好地解释了:Shortest match in regex from end). Also, to just display the ID part of your expression, you can include look-around assertions to remove part of the grep output (which is explained here: https://unix.stackexchange.com/questions/13466/can-grep-output-only-specified-groupings-that-match)。

将它们放在一起,以下正则表达式匹配从 "id": "", "createdAt" 的任何内容,并断言所需的“内部”匹配不包含模式 "id" 本身(这是我的理解是你想要的)并且只有 return 所有“内部”匹配项,每个都在单独的行中:

cat test | grep -Po '(?<=\"id\"\: \")((?:(?!\"id\").)*?)(?=\", \"createdAt)'

将return

62f0fac3-8b19-49de-866b-5f5cf23f2f9f
bd23d38d-8833-4fc4-b6c0-3906df0ed161

谢谢小伙伴。我也找到了另一个替代解决方案。但是你的更好


# cat test2 | awk -F"\", \"createdAt\": " '{for(i=1;i<=NF-1;i++)printf $i "\n" }' | while read id; do echo ${id: -36}; done
62f0fac3-8b19-49de-866b-5f5cf23f2f9f
bd23d38d-8833-4fc4-b6c0-3906df0ed161
cf4464cc-3ef7-4852-a4a0-2771538f6866
fbe16f4e-8f1c-4ffd-9d5e-86b2d2d419fb
36beae3e-208a-489e-a8ea-03f9c3e2de1b
386a08c3-35e6-4469-8b3a-7b49fd09da21
# cat test2  | grep -Po '(?<=\"id\"\: \")((?:(?!\"id\").)*?)(?=\", \"createdAt)'
62f0fac3-8b19-49de-866b-5f5cf23f2f9f
bd23d38d-8833-4fc4-b6c0-3906df0ed161
cf4464cc-3ef7-4852-a4a0-2771538f6866
fbe16f4e-8f1c-4ffd-9d5e-86b2d2d419fb
36beae3e-208a-489e-a8ea-03f9c3e2de1b
386a08c3-35e6-4469-8b3a-7b49fd09da21
#```