LINUX.ORG.RU

Поиск и удаление элемента массива

 ,


0

1

Всем доброго времени суток.

Поделитесь опытом, как на bash найти элемент массива и удалить его?

Допустим, имеется файл со списком людей:

user_list.csv

ivan.petrov
igor.ivanov
sergey.sokolov
gregoriy.pavlov

Имеется шаблон поиска:

declare -a EXCEPTION_LIST=(
igor.ivanov
gregoriy.pavlov
)

Хочу получить на выходе массив без EXCEPTION_LIST. По сути мы перебираем цикл в цикле и проверяем совпадение, если условие выполнено, то делаем unset "${USER_LIST[index]}", но, не могу придумать как получить этот самый индекс.

Кусок неработающего кода:

#!/usr/bin/env bash

declare -a USER_LIST=(`cat "/usr/local/script/user_list.csv" | awk '{print $1}' | tr '\n' ' '`)

######СПИСОК ПОЛЬЗОВАТЕЛЕЙ, КОТОРЫХ НЕОБХОДИМО ОСТАВИТЬ######
declare -a EXCEPTION_LIST=(
    igor\.ivanov
    gregoriy\.pavlov
)
#############################################################

for USER in "${!USER_LIST[@]}"
do
    for EXCEPTION in "${EXCEPTION_LIST[@]}"
    do
        if [[ "${USER_LIST[USER]}" == "$EXCEPTION" ]]
        then
            echo "${!USER_LIST[USER]}"
        fi
    done
done


exit 0


баш отключает мозг ? почему не сделать по нормальному через egrep ?

egrep -v 'igor\.ivanov|gregoriy\.pavlov' /usr/local/script/user_list.csv

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

Про grep была первая мысль. Но, хотелось сделать читаемо что-ли. Кто его знает сколько там эти людей будет и как часто они будут добавляться.

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

Ну сделай цикл с грепом, будет читаемо. Ну или собиралку регекспа для грепа.

crutch_master ★★★★★
()

Вообще на любителя конечно, но большими буквами переменные карячить это моветон какой-то. Когда вызываешь переменную - надо указывать $. В цикле переменная USER без $. В остальном должно работать.

Deleted
()
Последнее исправление: medossa (всего исправлений: 2)
Ответ на: комментарий от Deleted

Да, верно. Но, идей как получить индекс того или иного элемента не прибавилось. Похоже, только отдельной накапливаемой переменной.

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

Я понимаю, что python и perl больше подходят для этой задачи. Тут уже вопрос наличия навыков. Но, чую это будет тот самый толчок, чтобы начать постигать неизведанное.

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

Если выберешь Perl — буду тебе помогать, расскажу как вырубить левым в печень и двоечкой посадить на задницу любого хейтера. Если достигнешь нормального уровня с меня кизлярский нож.

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

Я понимаю, что python и perl больше подходят для этой задачи.

Не «и», а «или». Перл — идеальный выбор для жевания текста, питон более… универсальный.

Примеров не будет, так как готовые примеры гуглятся на раз.

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

В общем, ваше замечание сыграло ключевую роль. Накосячил с тем как пытался исключить элемент массива.

Так вроде как выводит то, что нужно.

#!/usr/bin/env bash

declare -a USER_LIST=(`cat "/usr/local/script/user_list.csv" | awk '{print $1}' | tr '\n' ' '`)

######СПИСОК ПОЛЬЗОВАТЕЛЕЙ, КОТОРЫХ НЕОБХОДИМО ОСТАВИТЬ######
declare -a EXCEPTION_LIST=(
    igor\.ivanov
    gregoriy\.pavlov
)
#############################################################

for USER in "${!USER_LIST[@]}"
do
    for EXCEPTION in "${EXCEPTION_LIST[@]}"
    do
        if [[ "${USER_LIST[USER]}" == "$EXCEPTION"* ]]
        then
            unset USER_LIST[$USER]
        fi
    done
done


exit 0

Спасибо, всем! Включая идеи изучить что-то новое.

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

Если выберешь Perl — буду тебе помогать

«Учи Perl, сука!» подошло бы под

расскажу как вырубить левым в печень и двоечкой посадить на задницу любого хейтера

куда лучше. (%

Если достигнешь нормального уровня с меня кизлярский нож.

Нормальному перлисту нож не нужен, он должен кодом калечить. (%

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

Нормальному перлисту нож не нужен, он должен кодом калечить. (%

Конечно есть больше одного способа сделать это, но нож предполагался в рамках решения бытовых задач. Например, пробить дыру в чайнике (небольшой закрытый сосуд с носиком, крышкой) чтоб заварить кофейку.

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

Конечно есть больше одного способа сделать это, но нож предполагался в рамках решения бытовых задач. Например, пробить дыру в чайнике (небольшой закрытый сосуд с носиком, крышкой) чтоб заварить кофейку.

Я хочу кофе — я просто беру кружку и пью из неё кофе. Я никогда не задумывался, откуда он там появляется. о_О

r3lgar ★★★★★
()

Дорогой боженька! Если ты есть, то пожалуйста залей тред горящей серой и оставь только следующую строку:

fgrep -vf excepton.list user_list.csv

Спасибо!

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

У меня fgrep -vf не сработал. Просто

grep -v 1.csv 2.csv
работает

Deleted
()
Ответ на: комментарий от hanharr
declare -a USER_LIST=(`cat "/usr/local/script/user_list.csv" | awk '{print $1}' | tr '\n' ' '`)


Какой кошмар.

read -a USER_LIST -d '\n' < /usr/local/script/user_list.csv
ashot ★★★★
()
Ответ на: комментарий от hanharr

Да и это:

for USER in "${!USER_LIST[@]}"
do
    for EXCEPTION in "${EXCEPTION_LIST[@]}"
    do
        if [[ "${USER_LIST[USER]}" == "$EXCEPTION"* ]]
        then
            unset USER_LIST[$USER]
        fi
    done
done

можно покороче

for EXCEPTION in "${EXCEPTION_LIST[@]}"; do
    USER_LIST=(${USER_LIST[@]/$EXCEPTION})
done

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

Конструкцию возьму на заметку, но в данном случае не прокатит. Там есть пачка записей вида manager.XXX, перечислять их не вариант, ибо придется тогда каждый раз править EXCEPTION_LIST, поэтому пусть уж цикл с условием с ними разбирается.

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

у нас в конторе есть старый сайт, написанный индусами на перле... сплошная портянка из копипасты, потому как разработка на perl не требует наличия мозга. идейный последователь великого и ужасного баша потому быстро умер как язык разработки. поддержка этой лапши слишком дорога. помимо perl и python есть равин (ruby) - это что-то среднее между обоими языками (регулярки как в перле - часть синтаксиса).

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

у нас в конторе есть старый сайт, написанный индусами на перле... сплошная портянка из копипасты

В этом отличие перлокода для продакшна я хорошего перлокода.

r3lgar ★★★★★
()

Может кто-то подскажет еще по такому моменту.

printf "%s\n" "${USERS_FOR_CLEAN[@]}"

Печатает каждый элемент массива с новой строки, а как туда еще можно подсунуть отступ для каждого элемента?

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

Там есть пачка записей вида manager.XXX, перечислять их не вариант, ибо придется тогда каждый раз править EXCEPTION_LIST

ЯННП. Ты же делаешь то же самое. У тебя 2 массива, один из файла, второй ты формируешь внутри скрипта.

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

import csv забыл

Ты, по ходу, забыл о чём ТС спрашивал.

# Делаем что-то с данными

Впрочем, негуманоидный синтаксис пистона способствует.

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

printf " <=здравствуйте, я отступ=> %s\n" «${USERS_FOR_CLEAN[@]}»

Спасибо и еще снизошло озарение, что пытался сделать "%s\t%s\n", а нужно было "\t%s\n"

ЯННП. Ты же делаешь то же самое. У тебя 2 массива, один из файла, второй ты формируешь внутри скрипта.

Блин, на работе на 6й центоси отказывался убирать элементы по шаблону. Когда допустим у меня в первом массиве manager.1 manager.2 manager.3, во втором я просто пишу manager.* и не сработало. Сейчас проделал тоже самое в убунту 18 и всё норм. Надо будет завтра посмотреть, может что не так сделал.

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

говноеды какие-то будут тут пердл пиарить у которого нету у функций аргументов (тяжелое башевское наследие). что мешает питон использовать в говнобаше?

(dev) sergey@sergey-laptop:~$ echo foo bar baz | python -c "import sys; input = sys.stdin.read().split(); print(' '.join(sorted(input)))"
bar baz foo
tz4678 ★★
()
Ответ на: комментарий от ashot

Да, ваш способ с массивами работает, спасибо.

В итоге накостылял сие. Вдруг кому-то захочется ужаснуться. :) Раз в месяц запустить сойдет, я считаю.

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

Просто соберите регулярное выражение для egrep'а из EXCEPTION_LIST'а.

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

у которого нету у функций аргументов (тяжелое башевское наследие)

Вообще-то есть. Но любители языка без нормального выделения блоков скобками предпочитают этого не знать. В Perl можно указывать аргументы в декларации, вопрос только в том, что это нафиг никому не нужно (особенно учитывая то, что у аргументов невозможно указать тип данных). Прямо первый же раздел perlsub'а: https://perldoc.perl.org/perlsub.html#Signatures

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

я просто нигде в перлокоде не видел чтобы их явно указывали. в js тоже так можно:

function foo() {
  const arg1 = arguments[0]
  const arg2 = arguments[1]
  // ...
}

Но никто так не делает... кроме альтернативно-одаренных любителей пёрдла. А зачем тебе тип переменной указывать в скриптовом языке?

Кстати,еще любителя баша можно опознать в яваскрипте по конструкциям вида:

(somevar === 42) && (/* some shit code */)
tz4678 ★★
()
Ответ на: комментарий от tz4678

А зачем тебе тип переменной указывать в скриптовом языке?

Скриптовый язык - это НЁХ. С таким же успехом можно всё, что не Си и Си++, называть скриптовым языком.

В Perl внутреннее приведение типов существует, и как раз отсутствие возможности указать тип явно (как и «привести» его) - один из рудиментов языка. Когда это всё придумывали считалось, что от типов у людей голова «бобо», и лучше делать эвристику внутри интерпретатора, чем заставлять думать о том, какое представление переменной нужно в данном месте - строковое или числовое (в Perl одна переменная может существовать сразу в нескольких ипостасях с т.з. внутренней логики интерпретатора).

Если не использовать сигнатуры, достаточно просто написать:

sub relocateSun {
  my ($x, $y, $z) = @_;
  ...
}
- не нужно индивидуально каждый $_[0], $_[1] и т.д. присваивать. За 9 лет перловой практики у меня не было проблем с присваиванием аргументам и функций никогда. Вариант с сигнатурами читабельнее, но никакого прямо «прорыва» в понимании написанного он не даёт, это скорее рюшечки. К тому же, часто (очень) входящие аргументы преобразуются в реально используемые переменные сразу после их появления, поэтому если тебе на вход идёт x, а в объективной действительности тебе нужен везде x^2, то нет большого смысла сразу лексически загаживать буковку «x» нигде не нужным значением. Как и возводить её сразу в степень - тоже странно. А вот $x = $_[1] ** 2 - в самый раз.

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

а редакторы как понимают эту писанину. вот я справку по функции вызываю и хочу увидеть список аргументов. я что-то увижу? - наврядли. если ты пишешь эпичные однострочники и простые скрипты для замены башу, то оно не очень важно. учить perl в 2018 не имеет смысла. пусть лучше php освоит хотя бы деньги перестанет у мамки клянчить.

tz4678 ★★
()

Такие вещи очень просто делаются на ассоциативных массивах.

#!/bin/bash

USER_LIST="user_list.csv"

declare -a EXCEPTION_LIST=(
igor.ivanov
gregoriy.pavlov
x.y
)

declare -a NAMES
declare -A ASSOC_NAMES
num=0
while read line; do
        ASSOC_NAMES["$line"]=$num
        NAMES[num++]=$line
done < "$USER_LIST"

for e in "${EXCEPTION_LIST[@]}"; do
        num=${ASSOC_NAMES["$e"]}
        [[ -n $num ]] && unset NAMES[num]
done

for e in "${NAMES[@]}"; do
        echo "$e"
done

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