使用 sed 无法使用“-”定界符拆分字符串
splitting string with "- " delimiter using sed not working
我有以下字符串,每行由换行分隔作为输入字符串
string="name: MAIN_ROLE
description: ROLE DESCRIPTION
readOnly:
roleReferences:
- roleTemplateAppId: app1
roleTemplateName: template2
name: Name1
- roleTemplateAppId: app2
roleTemplateName: template2
name: Name2
"
我喜欢将 YAML 字符串打印成逗号分隔的字符串,如下所示。输入字符串可以在“-”之后有任意数量的组件,这会产生新记录,但 MAIN_ROLE 值保持不变,第一列:
MAIN_ROLE,Name1,template1,app1
MAIN_ROLE,Name2,template2,app2
我尝试用下面的代码用“-”拆分行,但我没有得到正确的结果
echo "$a" | sed -n $'/^- $/,/^- $/p' <<< $string
您可以这样使用awk
:
awk 'NR==1{a=;cnt=0} /^-/{rta[cnt]=;getline;rtn[cnt]=; getline; n[cnt]=;cnt++} END{ for(i=0;i<cnt;i++) { print a","n[i]","rtn[i]","rta[i] } }' file > outputfile
参见 online demo:
#!/bin/bash
string="name: MAIN_ROLE
description: ROLE DESCRIPTION
readOnly:
roleReferences:
- roleTemplateAppId: app1
roleTemplateName: template1
name: Name1
- roleTemplateAppId: app2
roleTemplateName: template2
name: Name2
"
awk 'NR==1{ # When on Line 1
a=;cnt=0 # Set a (main name) and cnt (counter) vars
}
/^-/{ # When line starts with -
rta[cnt]=; getline; # Add role template app ID to rta array, read next line
rtn[cnt]=; getline; # Add role template name to rtn array, read next line
n[cnt]=;cnt++ # Add name to n array, increment the cnt variable
}
END{ # When the file processing is over
for(i=0;i<cnt;i++) { # Iterate over the found values and...
print a","n[i]","rtn[i]","rta[i] # print them
}
}' <<< "$string"
# => MAIN_ROLE,Name1,template1,app1
# MAIN_ROLE,Name2,template2,app2
根据您展示的示例,您可以尝试遵循 awk
程序。这可以在很少的条件下简单地完成,而不是使用阵列系统。
awk '
BEGIN{ OFS="," }
/roleTemplateAppId/{
if(name && template){
print "MAIN_ROLE",name,template,$NF
}
name=template=""
}
/roleTemplateName:/{
template=$NF
next
}
/name:/{
name=$NF
}
END{
if(name && template){
print "MAIN_ROLE",name,template,$NF
}
}
' Input_file
说明: 为以上添加详细说明。
awk ' ##Starting awk program from here.
BEGIN{ OFS="," } ##Setting OFS to , in BEGIN section.
/roleTemplateAppId/{ ##Check if line contains roleTemplateAppId then do following.
if(name && template){ ##check if name and template is SET then do following.
print "MAIN_ROLE",name,template,$NF ##Printing MAINE_ROLE name, template and last field value here.
}
name=template="" ##Nullifying name and template here.
}
/roleTemplateName:/{ ##Check if roleTemplateName: is found in current line then do following.
template=$NF ##Setting template to last field of current line.
next ##next will skip all further statements from here.
}
/name:/{ ##Checking condition if line contains name: then do following.
name=$NF ##Setting name value as last field name.
}
END{ ##Starting END block of this program from here.
if(name && template){ ##check if name and template is SET then do following.
print "MAIN_ROLE",name,template,$NF ##Printing MAINE_ROLE name, template and last field value here.
}
}
' Input_file ##Mentioning Input_file name here.
我有以下字符串,每行由换行分隔作为输入字符串
string="name: MAIN_ROLE
description: ROLE DESCRIPTION
readOnly:
roleReferences:
- roleTemplateAppId: app1
roleTemplateName: template2
name: Name1
- roleTemplateAppId: app2
roleTemplateName: template2
name: Name2
"
我喜欢将 YAML 字符串打印成逗号分隔的字符串,如下所示。输入字符串可以在“-”之后有任意数量的组件,这会产生新记录,但 MAIN_ROLE 值保持不变,第一列:
MAIN_ROLE,Name1,template1,app1
MAIN_ROLE,Name2,template2,app2
我尝试用下面的代码用“-”拆分行,但我没有得到正确的结果
echo "$a" | sed -n $'/^- $/,/^- $/p' <<< $string
您可以这样使用awk
:
awk 'NR==1{a=;cnt=0} /^-/{rta[cnt]=;getline;rtn[cnt]=; getline; n[cnt]=;cnt++} END{ for(i=0;i<cnt;i++) { print a","n[i]","rtn[i]","rta[i] } }' file > outputfile
参见 online demo:
#!/bin/bash
string="name: MAIN_ROLE
description: ROLE DESCRIPTION
readOnly:
roleReferences:
- roleTemplateAppId: app1
roleTemplateName: template1
name: Name1
- roleTemplateAppId: app2
roleTemplateName: template2
name: Name2
"
awk 'NR==1{ # When on Line 1
a=;cnt=0 # Set a (main name) and cnt (counter) vars
}
/^-/{ # When line starts with -
rta[cnt]=; getline; # Add role template app ID to rta array, read next line
rtn[cnt]=; getline; # Add role template name to rtn array, read next line
n[cnt]=;cnt++ # Add name to n array, increment the cnt variable
}
END{ # When the file processing is over
for(i=0;i<cnt;i++) { # Iterate over the found values and...
print a","n[i]","rtn[i]","rta[i] # print them
}
}' <<< "$string"
# => MAIN_ROLE,Name1,template1,app1
# MAIN_ROLE,Name2,template2,app2
根据您展示的示例,您可以尝试遵循 awk
程序。这可以在很少的条件下简单地完成,而不是使用阵列系统。
awk '
BEGIN{ OFS="," }
/roleTemplateAppId/{
if(name && template){
print "MAIN_ROLE",name,template,$NF
}
name=template=""
}
/roleTemplateName:/{
template=$NF
next
}
/name:/{
name=$NF
}
END{
if(name && template){
print "MAIN_ROLE",name,template,$NF
}
}
' Input_file
说明: 为以上添加详细说明。
awk ' ##Starting awk program from here.
BEGIN{ OFS="," } ##Setting OFS to , in BEGIN section.
/roleTemplateAppId/{ ##Check if line contains roleTemplateAppId then do following.
if(name && template){ ##check if name and template is SET then do following.
print "MAIN_ROLE",name,template,$NF ##Printing MAINE_ROLE name, template and last field value here.
}
name=template="" ##Nullifying name and template here.
}
/roleTemplateName:/{ ##Check if roleTemplateName: is found in current line then do following.
template=$NF ##Setting template to last field of current line.
next ##next will skip all further statements from here.
}
/name:/{ ##Checking condition if line contains name: then do following.
name=$NF ##Setting name value as last field name.
}
END{ ##Starting END block of this program from here.
if(name && template){ ##check if name and template is SET then do following.
print "MAIN_ROLE",name,template,$NF ##Printing MAINE_ROLE name, template and last field value here.
}
}
' Input_file ##Mentioning Input_file name here.