为什么我的变量没有在bash中保持其值?

时间:2019-05-26 00:33:06

标签: bash

我很困惑。

我已经编写了一个bash脚本,用于根据该行中的子字符串将行分类为类别。

这是我的示例“ lines.txt”

i am line1
i am line2

如果一行包含“ line1”,则应将其分类为组“ l1”。如果包含“ line2”,则应将其分类为“ l2”组

问题在于保存类别的变量没有保留其值,我也不知道为什么。这是脚本。

#!/bin/bash
categories="l1 l2"

l1="
    line1
"

l2="
    line2
"

# match line1
cat lines.txt | while read fline
do
    cate="no match"

    for c in $categories
    do
        echo "${!c}" | while read location
        do
            if [ ! -z "$location" ] && [[ "$fline" =~ "$location" ]]
            then
                echo "we are selecting category $c"
                cate="$c"
                break
            fi
        done

        if [ "$cate" != "no match" ]
        then
            echo "we found a match"
            break
        fi
    done

    echo "$cate:$fline"
done

exit 0

当我运行它时,我会看到输出

we are selecting category l1
no match:i am line1
we are selecting category l2
no match:i am line2

这意味着我们正在选择正确的组,但是退出嵌套的“ while”循环时我们不记得它了。

为什么我的变量不保留其值,我该如何解决?

1 个答案:

答案 0 :(得分:2)

while循环由于管道而在子shell中执行。这意味着名称“ cate”实际上是指两个不同的变量。一个在while循环外部,另一个在子外壳内部的循环内部。当子外壳退出时,该值将丢失。

一种解决方法是使用这样的重定向

while read line; do
...
done < $myfile

如果表达式更复杂,并且您需要在子Shell中执行某些操作,则可以使用进程替换(感谢David Rankin提醒我这一点)。

while read -r line; do
...
done < <(find . -iname "*sh")