Почему моя переменная не содержит значения в bash? - PullRequest
0 голосов
/ 26 мая 2019

Я ужасно озадачен.

Я написал скрипт 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 Ответ

2 голосов
/ 26 мая 2019

Цикл while выполняется в подоболочке из-за конвейера.Это означает, что имя «cate» действительно относится к двум различным переменным.Один вне цикла while, а другой внутри цикла внутри подоболочки.При выходе из подоболочки это значение теряется.

Чтобы обойти это, используйте перенаправление, подобное этому

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

Если выражение более сложное и вам нужно что-то выполнить вsubshell, тогда вы можете использовать процесс подстановки (спасибо Дэвиду Ранкину за напоминание об этом).

while read -r line; do
...
done < <(find . -iname "*sh")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...