Bash-解析和变量 [英] Bash - Parsing and variables

查看:73
本文介绍了Bash-解析和变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

case 4.1
Info for unit 1 starts now
info1
info2
info3
info5  - the one I want
info6
info7
Info for unit 2 starts now
info1
info2
info3
info5  - the one I want
info6
info7
endcase 4.1

这两个单位的信息在文件中打印了1000多次.

The info for the 2 units are printed out over 1000 times in the file.

我的算法如下:

while read line
do
    if line contains unit1
    then current_unit=1
    if line contains unit2
    then current_unit2

    if line contains info5
    then 
         if current_unit = 1
            then unit1_val = *the relevant info from this line*
         elif current_unit = 2 
             then unit2_val = *the relevant info from this line*

    if both unit1_val > 20 && unit2_val > 20
    then pass

简短版本:提取我需要的值,如果在某个时候两个值都超过某个值,则测试通过.我也在尝试使用Bash

Short version: pull the values i need, if at some point both values are over a certain value, test passed. I'm also trying to do this using Bash

为清楚起见进行我遇到的问题是将变量传入和传出if语句.我的解析和比较很好,但是当我到达最后一个if时,值就不存在了,因为它们对于if-fi来说是本地的(视情况而定)(或视情况而来)

Edit for clarity: The problem that I', having is passing variables in and out of if statements. My parsing and comparisons are fine, however When i get to the last if, the values are not there, because they are local to the if - fi they come from (or dont come from, as the case may be)

    if [[ $line == *"info5"* ]]
    then
            CURRENT_UNIT=5
    fi

    if [[ $line = *"info6"* ]]
    then
            CURRENT_UNIT=6     
    fi

    if [[ $line =~ "text i want" ]]
    then
            if [[ $CURRENT_UNIT -eq 5 ]]
            then
                    UNIT_5_MEM=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }')
            elif [[ $CURRENT_VC -eq 6 ]]
            then    UNIT_6_MEM=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }')
            fi
    fi

    if [[ $UNIT_5_MEM -gt 20 && $UNIT_6_MEM -gt 20 ]]
    then
            echo "Passed"
    fi

推荐答案

我收集到您发布问题的原因是,当while循环结束时,在while循环中设置的变量似乎消失了.

I gather that the reason you posted the question is because variables set inside your while loop seem to disappear once the while loop finishes.

这是因为当您将while循环作为管道的一部分执行时,它在子shell中运行,并且当子shell退出时,父shell的环境保持不变,不受子shell中发生的任何事情的影响.

This is because when you execute the while loop as part of a pipeline, it runs in a subshell, and when the subshell exits, the environment of the parent shell remains unchanged, unaffected by whatever was happening in the subshell.

您可以通过使用重定向或进程替换而不是管道获取输入数据,以bash的方式解决此问题.例如,这不起作用:

You can get around this in bash by getting your input data using redirection or process substitution rather than a pipeline. For example, this doesn't work:

cat inputfile | while read line; do
  case "$line" in
    foo*) output=$line ;;
  esac
done
echo "output=$output"

这确实起作用:

while read line; do
  case "$line" in
    foo*) output=$line ;;
  esac
done < inputfile
echo "output=$output"

这是我想出的:

#!/bin/bash

declare -A output

while read line; do
    case "$line" in
        *unit*)
            unit=$(awk '{print $4}' <<<"$line")
            ;;
        info5*)
            output[$unit]="$line"
            echo "FOUND: unit=$unit, line=$line" >&2
            ;;
    esac
done < inp1

echo "Output 1:"
printf "%s\n" "${output[@]}"

### Alternately:

echo "Output 2:"
for ((i=${#output[@]}; i > 0; i--)); do
    echo "unit=$i, line=${output[$i]}"
done

我得到的输出是:

FOUND: unit=1, line=info5  - the one I want
FOUND: unit=2, line=info5  - the one I want
Output 1:
info5  - the one I want
info5  - the one I want
Output 2:
unit=2, line=info5  - the one I want
unit=1, line=info5  - the one I want

如果您真的想将内容存储到像 UNIT_5_MEM 这样的变量中,我想可以,但是数组看起来更干净.另外,在没有看到您正在处理的数据的情况下,很难知道您要使用 awk 实现什么,因此我将其排除在答案之外.

If you really want to store things to variables like UNIT_5_MEM, I suppose you can, but arrays seem cleaner. Also, without seeing the data you're processing, it's difficult to know what you're trying to achieve with awk, so I've left that out of my answer.

这篇关于Bash-解析和变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆