我非常困惑。

我编写了一个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

当我运行它时,我看到了output

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

这意味着我们正在选择正确的组,但是当我们退出nested "while"循环时我们不记得它。

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

分析解答

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

围绕这个get的方法是使用像这样的redirect

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

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

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