根据条件在文件上打印行的shell脚本

doinxwow  于 11个月前  发布在  Shell
关注(0)|答案(3)|浏览(159)

我有一个这样的文件

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"= Inactive
  • line "运行示例数"= 0

从提供的示例文件中,我应该只期望TEST11_1
任何帮助将不胜感激。问候。

daupos2t

daupos2t1#

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 }
'

字符串

cgyqldqp

cgyqldqp2#

由于输入 almost 看起来像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,应用过滤器,Map到.Acronym,然后每行打印一个结果。

ddarikpa

ddarikpa3#

有很多方法可以做到这一点,其中一种方法是使用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函数中定义。
我不确定这是否足够清楚,因为脚本变得有点冗长。如果你有任何问题,请随时提问。

相关问题