LINUX.ORG.RU

Функция удаления элемента из списка

 


0

1

Требуется: реализовать функцию извлечения элемента из списка на pure BASH, без привлечения каких-либо сторонних утилит.
Это же элементарно, Ватсон!

lst_rm () {
 local lst="$1"
 local what2rm="$2"
 local sep="${3:- }"
 [[ $lst =~ (^|.+${sep})${what2rm}(${sep}.+|$) ]] && \
  echo -n "${BASH_REMATCH[1]%$sep}${BASH_REMATCH[1]:+${BASH_REMATCH[2]:+$sep}}${BASH_REMATCH[2]#$sep}" || \
  echo -n "$lst"
 return 0
}
Может, есть варианты сделать это проще? ;)

★★★★★

Может, я неправильно понял задачу, но вот так не покатит?

#!/bin/bash

LIST="one two three"
TO_RM="$1"
TMP_LIST=""
for VAR in $LIST
do
        if [ "$VAR" != "$TO_RM" ]
        then
                TMP_LIST="$TMP_LIST $VAR"
        fi
done
LIST=$TMP_LIST
echo $LIST

P.S. код в топике не распарсил.

shell-script ★★★★★
()
Последнее исправление: shell-script (всего исправлений: 1)
Ответ на: комментарий от shell-script

P.S. код в топике не распарсил.


Всё потому что ваш код - это Shell, а мой - это BASH. Из того, что BASH может выполнять классический Shell-код ещё не следует BASH == Shell :) И да, программы в стиле «фак мой мозг» - это вообще «коронная» особенность всех bash-хакеров.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от shell-script

Понятно, что циклом можно всё, что угодно сделать. Вопрос в том, насколько это быстро работает.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Ну, тут надо смотреть по размеру массива, но для примера вот эксперимент провёл:

$ time bash bash_list.sh two
1792

real    0m0.227s
user    0m0.222s
sys     0m0.002s
1792 - это количество элементов массива.

shell-script ★★★★★
()
Ответ на: комментарий от shell-script

LIST=«one two three»

В баше-то есть то, что можно назвать «списком». А это какой-то недотикль-like.

anonymous
()
Ответ на: комментарий от ABW

Тем, что ${List/$Elem/} Удалит только сам элемент, не учитывая семантику «списка».
Список - строка с разделителям, элемент должен быть обрамлён разделителями, в роли которых могут выступать и конец/начало строки. В лучшем случае ${List/$Elem/} удалит элемент, но оставит один лишний разделитель, а в худшем - вырежет кусок из другого элемента, содержащего этот как подстроку.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

А это какой-то недотикль-like.

Иногда, со строками работать удобнее, чем с массивами, да и сами исходные данные могут быть такой строкой с разделителями - взять хотя бы тот же PATH.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от Kalashnikov

Для начала возьми язык программирования.

Assembler? Кроме Assembler'а мне ещё FreeBASIC нравится. Perl вот временами юзаю (да что далеко ходить - непосредственно at a present time юзаю).
BASH - это не язык для тех, кто его не асилил и у кого руки из Ж растут. Для остальных он вполне себе язык - так-то.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

zsh так и не стал популярным, его (почти) везде нужно ставить дополнительно, а BASH по дефолту в Linux'ах водится.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Иногда, со строками работать удобнее, ... взять хотя бы тот же PATH.

Это не _удобнее_, это _соотвествует_: «быстро и грязно». Magic string (или как это называется), и ":" в пути не должен находиться.

anonymous
()
Ответ на: комментарий от Kalashnikov

Ну-ка, ну-ка, мне прямо интересно стало: и сколько это у вас строк корректное извлечение элемента из строки-«списка» займёт на Сях? Подчёркиваю: именно корректное извлечение, при котором не остаётся глюков в виде висячих разделителей в конце или начале строки или удвоенного разделителя внутри строки. У меня на BASH это фактически однострочная конструкция:

[[ $lst =~ (^|.+${sep})${what2rm}(${sep}.+|$) ]] && lst="${BASH_REMATCH[1]%$sep}${BASH_REMATCH[1]:+${BASH_REMATCH[2]:+$sep}}${BASH_REMATCH[2]#$sep}"
Или вы намекаете на то, что на Perl'е оно красивее? Так Perl - специализированный язык для обработки текстов изначально, ему как бы по статусу положено.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

То, что в PATH допущен этот идиотский косяк с ограничением на содержание ":" внутри собственно одного из путей - не мой косяк, а вот извлечь путь из PATH/добавить путь в PATH требуется часто.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Собственно, перед тем как добавить путь в PATH я его сначала оттуда пытаюсь извлечь. Причина этого элементарно проста: мне нужно контролировать порядок просмотра PATH. А вообще я озаботился написанием функций lpop и lpush (в итоге они так обозвались) для TASKS_QUEUE в parex.inc
Почему я решил заменить красивый ассоциативный массив, содержащий /proc/$PID/cmdline на какие-то строки? Да очень просто: я хочу «пулы задач», чтобы можно было push_task вызывать внутри процесса, также запущенного push_task'ом. Получится ассоциативный массив с ключами-ID'шниками пулов и значениями - строками с PID'ами процессов пула. В этом плане в BASH конечно дико не хватает ссылок как в Perl'е.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от Kalashnikov

В BASH тоже не нужно. Есть declare -a arr=(el1 el2 el3 el4). Почитайте статью о BASH на педивикии - там то, что касается массивов частично мной написано.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от ABW

Конечно я думал об этом направлении, но так чтобы решить задачу в одну строку - даже с использованием shopt -s extglob не получится ИМХО. Другое дело, что эту же задачу можно было реализовать более быстрым кодом, поскольку конструкция [[ $var =~ regex ]] в BASH довольно затратна.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от fragmentor

Если дадите код с использованием sed, сравню :) Кстати, вопрос резонный, потому что я действительно сталкивался с тем, что конструкции, написанные на чистом BASH, оказываются медленнее тех, что активно exec'ают всякие grep'ы и sed'ы.

DRVTiny ★★★★★
() автор топика

Хватит насиловать autoexec.bat

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.