提问人:Dave Dolone 提问时间:10/31/2023 最后编辑:shellterDave Dolone 更新时间:11/1/2023 访问量:41
根据条件在文件上打印行的 shell 脚本
shell script that print lines on a file based on conditions
问:
我有一个这样的文件
Name: Test1
Acronym: TEST11
Description: null
Toolkit: false
Tracks:
List:
Name: 1st_test
Acronym: TEST11_1
Created On: 2016-03-22 15:25:27.355
Created By: User.9
Is Default: false
State: State[Inactive]
Capability: Capability[Standard]
No of running instances: 0
Name: 2nd_test
Acronym: TEST11_2
Created On: 2016-03-23 15:07:18.955
Created By: User.9
Is Default: true
State: State[Active]
Capability: Capability[Standard]
No of running instances: 0
Name: 3rd_test
Acronym: TEST11_3
Created On: 2016-03-22 11:54:45.276
Created By: User.9
Is Default: false
State: State[Inactive]
Capability: Capability[Standard]
No of running instances: 1
如果出现以下情况,我需要一个打印首字母缩略词(列表下的脚本)的脚本:
- line “Is Default” = false
- 行 “State” = 非活动
- 行“正在运行的实例数”= 0
从提供的示例文件中,我应该只期望TEST11_1
任何帮助将不胜感激。 问候。
答:
1赞
Charles Duffy
10/31/2023
#1
awk -F'[]:[:space:][]+' '
/^[[:space:]]*$/ {
if((isDefault == "false") && (instance_count == "0") && (state == "Inactive")) {
print(acronym)
}
acronym=""
instance_count=0
isDefault=unknown
state=unknown
}
END {
if((isDefault == "false") && (instance_count == "0") && (state == "Inactive")) {
print(acronym)
}
}
/No of running instances:/ { instance_count=$6 }
/Acronym/ { acronym=$3 }
/Is Default:/ { isDefault = $4 }
/State:/ { state=$4 }
'
1赞
Benjamin W.
11/1/2023
#2
由于输入几乎看起来像 YAML,我们可以稍微作弊并将其转换为实际的 YAML,然后使用 yq:
sed -E 's/ ( Name:)/-\1/' infile \
| yq '
.Tracks.List
| map(
select(
.["Is Default"] | not
and .State == "State[Inactive]"
and .["No of running instances"] == 0
)
| .Acronym
)
| .[]
'
sed 命令在每个前面加上两个空格,这可能是最脆弱的部分。-
Name:
然后,yq 钻取到 ,应用过滤器,映射到 ,然后每行打印一个结果。.Tracks.List
.Acronym
评论
0赞
Dave Dolone
11/2/2023
我确定它有效,但我错过了 yq 命令,所以我无法测试它。
0赞
dbran
11/1/2023
#3
有很多方法可以做到这一点。我想到的一个是用来解析文件,然后遍历每个列表段。grep
下面是一个完整的示例:
#!/usr/bin/env bash
shopt -s extglob
# name of the file
file=file.txt
# extract the "Name: ..." lines of file
list_names="$(grep -E '\s+Name' "$file")"
list=()
# add each "Name: ..." line to the "list" array
while IFS= read -r line; do
# trim string
list+=("${line##*( )}")
done <<< "$list_names"
# check if all three conditions are met
function check {
grep --quiet --fixed-strings \
'Is Default: false' <<< "$1" &&
grep --quiet --fixed-strings \
'State: State[Inactive]' <<< "$1" &&
grep --quiet --fixed-strings \
'No of running instances: 0' <<< "$1"
}
# loop through each list segment and check
# if conditions are met for each one
for f in "${list[@]}"; do
# select and store all key/value pairs of each instance
settings="$(grep -A 7 "$f" "$file")"
# print "Acronym" value if all three strings
# are found in the check function
if check "$settings"; then
output="$(grep 'Acronym' <<< "$settings")"
# trim string
echo "${output##*( )}"
fi
done
脚本的输出是 ,因为满足所有三个条件。条件在函数中定义。Acronym: TEST11_1
TEST11_1
check
我不确定这是否足够清楚,因为脚本变得有点冗长。如果您有任何问题,请随时提问。
评论
0赞
Dave Dolone
11/2/2023
这个效果很好。非常
评论