Bash-解析和变量 [英] Bash - Parsing and variables
问题描述
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屋!