Цикл For -Bash не читает мои переменные

Я столкнулся с этим только что. Есть довольно простое решение, которое сработало для меня. Я хотел использовать массив, содержащий имя устройства и позицию на экране, чтобы отобразить карту клавиш для устройства. Я сделал следующее :Я объединил имя устройства и соответствующую позицию на экране в одну строку, используя разделитель (, в моем случае я использовал.)который, как я знал, не появится ни в одном из моих значений. Затем я использовал cut, чтобы разбить составные значения на их компоненты. при необходимости. Возможно, есть более чистый и простой способ сделать это, но это просто для того, чтобы показать, что вы можете создать многомерный массив в некотором роде в bash, даже если он его не поддерживает :

.

#!/bin/bash

# List of devices and screen positions for key maps.
DEV_LIST=( g13.+2560+30 g510s.+3160+30 g502.+2560+555 )

# This just echoes the device name and the screen position.
for DEV in "${DEV_LIST[@]}"; do
    DEVICE=$(echo $DEV | cut -f1 -d.)
    SCREEN_POSITION=$(echo $DEV | cut -f2 -d.)
    echo "$DEVICE"
    echo "$SCREEN_POSITION"
done

exit

Это чем-то похоже на ответ Coop.Computer .

0
21.04.2021, 19:28
2 ответа

вы можете повторить эту последовательность, чтобы получить диапазон переменных:

#!/bin/bash
LINES=1
LASTLINE=10
for i in $(seq $LINES $LASTLINE )
do
 echo $i
done

выход:

1
2
3
4
5
6
7
8
9
10
-2
28.04.2021, 22:52
LASTLINE=$(grep -P '### Stop marker ###' file.txt | wc -l)

Это скажет вам сколько строк соответствует этому шаблону, но не покажет, где они находятся. Если в файле есть один маркер, возвращается 1. Вам нужно будет использовать что-то вроде grep -n(--line-number), чтобы получить номера строк.

file=sed -n $i'p' file.txt

Вероятно, это должно быть file=$(sed...), то есть с подстановкой команды для захвата вывода sed. Но если вы делаете это в цикле, вы читаете весь файл для каждой итерации цикла, глупая трата времени, и если файл длинный, это займет целую вечность.

Вот в чем вопрос Почему использование цикла оболочки для обработки текста считается плохой практикой? , ссылка на которую была здесь ранее. Обратите внимание, что плохой практикой является обработка , изменение текста. Выполнение команд на основе некоторых данных в файле с использованием оболочки вполне нормально; оболочка существует для запуска команд.

Итак, просто прокрутите файл один раз и обнаружите маркер остановки в оболочке:

#!/bin/bash
i=0
while IFS= read -r line; do 
    if [[ $line == '### Stop marker ###' ]]; then
        break;
    fi
    i=$((i + 1))
    echo "line $i, do some stuff with '$line'"
done < file.txt

([[.. ]]— это кш -изм. Его можно заменить на caseв оболочке POSIX.)

Или пусть какой-нибудь внешний инструмент обработки текста обрабатывает маркер остановки, а оболочка просто запускает команды:

#!/bin/sh
i=0
< file.txt sed -n -e '/### Stop marker ###/q' -e p |
while IFS= read -r line; do
    i=$((i + 1))
    echo "line $i, do some stuff with '$line'"
done

Если вы действительно хотите выполнить цикл в стиле for (i = 0; i < end; i++), вы можете сначала прочитать весь файл в массив, но если вам не нужно произвольный доступ к строкам, это совершенно не нужно. Потоковая передача через файл гораздо более естественна.

2
28.04.2021, 22:52

Теги

Похожие вопросы