我正在嘗試從 AWS 獲取 IAM 策略并將其添加到以下特定格式的文本檔案中。我想在“}”括號結束之前洗掉檔案中 policy= 之后的所有內容。
這是我擁有的文本檔案示例。但是原始檔案可以在同一個檔案中有多個 example_policy 實體。
"example1_policy" {
name="example"
policy=jsonencode(
{
Statement=[
{
Action=[
s3:*
]
Effect="Allow"
},
]
Version="2012-10-17"
}
)
}
"example2_policy" {
name="example2"
policy=jsonencode(
{
Statement=[
{
Action=[
s3:*
]
Effect="Allow"
},
]
Version="2012-10-17"
}
)
}
"example3_policy" {
name="example3"
policy=jsonencode(
{
Statement=[
{
Action=[
s3:*
]
Effect="Allow"
},
]
Version="2012-10-17"
}
)
}
預期輸出:
"example1_policy" {
name="example1"
policy=
}
"example2_policy" {
name="example2"
policy=
}
"example3_policy" {
name="example3"
policy=
}
或者
"example1_policy" {
name="example1"
policy=<placeholder>
}
"example2_policy" {
name="example2"
policy=<placeholder>
}
"example3_policy" {
name="example3"
policy=<placeholder>
}
根據@Wiktor 的評論,我嘗試了這個命令
sed -i '/policy=/,/^\s*)\s*$/d' test.txt
輸出:policy= 應該保持不變。
"example_policy" {
name="example"
}
uj5u.com熱心網友回復:
你可以在 Python 中很容易地做到這一點,因為你有狀態:
def clean(s, pattern='policy='):
pre, post = s.split(pattern)
harmony = True
quote = False
braces = 0
for i, char in enumerate(post):
if harmony and char == '\n':
return f'{pre}{pattern}{post[i:]}'
if not quote:
if char == '(':
braces = 1
elif char == ')':
braces -= 1
elif char in ('"', "'"):
quote = char
harmony = braces == 0
elif quote == char:
quote = False
這甚至會忽略包含在字串中的大括號(“ 和 ' 字串)。
所以,這個版本也適用于更復雜的字串:
"example_policy" {
name="example"
policy=jsonencode(
{
Statement=[
{
Action=[
s3:*
]
Effect="Al)l'ow"
},
]
Version='"2012-10)-17"'
}
)
}
您可以輕松擴展它以支持其他型別的大括號或引號。唯一的區別是您需要為大括號使用計數器,因為開始和結束字符不同,而對于引號,您只需要在匹配串列中添加額外的字符 - 因為引號中的其他所有內容都被忽略了,您只需要記住引號是用哪個字符打開的。
使用正則運算式執行此操作會比較棘手,因為它們僅支持有限大括號嵌套。
要洗掉同一字串中的多個策略,我們需要定義一個輔助函式:
def clean(s):
harmony = True
quote = False
braces = 0
for i, char in enumerate(s):
if harmony and char == '\n':
return s[i:]
if not quote:
if char == '(':
braces = 1
elif char == ')':
braces -= 1
elif char in ('"', "'"):
quote = char
harmony = braces == 0
elif quote == char:
quote = False
return s
然后將“清潔助手”應用于每個單獨的塊的主要功能:
def clean_all(s, pattern='policy='):
head, *tail = s.split(pattern)
return f'{head}{pattern}{pattern.join(clean(part) for part in tail)}'
uj5u.com熱心網友回復:
您可以使用以下 GNU sed 命令:
sed -i '/policy=/,/^\s*)\s*$/{/policy=/!d};s/\(policy=\).*/\1<placehlder>/' file
請參閱在線演示。詳情:
/policy=/,/^\s*)\s*$/policy=- 查找行與僅)包含用零個或多個空格包圍的字符的行之間的行塊{/policy=/!d}- 防止洗掉找到的塊中的第一行并洗掉其他行s/\(policy=\).*/\1<placehlder>/- 全部替換policy=為<placeholder>.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/425932.html
上一篇:帶有`jq`和`grep`的多個`if`條件不正確匹配,并在根本不匹配時回傳true
下一篇:修剪AWK中的多余空格
