В языках программирования функции могут возвращать "сложные" объекты. Массивы, хэши-словари. Есть что-то похожее для Shell (Bash, или иное)?Я пробежался поиском - не увидел как сделать так, что код можно быстро будет понять через полчаса после написания. :)
Я так понимаю, что правильный ответ - Perl, с выключенными "предохранителями". Там можно всё нужное, да. Именно. Но вопрос таки про Bash или иной распространённый Shell.
Может быть есть какой-то известный, распространённый стиль/стратегия, которые позволяют обойтись?
Есть вот такой код (Bash 4):
#!/bin/bashset -x
set -edeclare -r fileTmpA="/tmp/$( basename "${0}" )_A"
declare -r fileTmpB="/tmp/$( basename "${0}" )_B"
trap "rm '${fileTmpA}' '${fileTmpB}'" EXIT HUP INT TERM
################################################
declare -A dictionary_A
declare -A dictionary_Becho -ne "0000\n1111\n" > "${fileTmpA}"
echo -ne "2222\n3333\n" > "${fileTmpB}"while read value ; do
key="$( echo "${value}" | md5sum | cut --delim=' ' --field 1 )"
dictionary_A["${key}"]="${value}"
done <<< "$( cat "${fileTmpA}" )"while read value ; do
key="$( echo "${value}" | md5sum | cut --delim=' ' --field 1 )"
dictionary_B["${key}"]="${value}"
done <<< "$( cat "${fileTmpB}" )"
################################################
set +x
echo "________________________________________________"
for key in "${!dictionary_A[@]}" "${!dictionary_B[@]}" ; do
echo "Have key: ${key}"
done
А теперь фейковый вариант.
Bash так не умеет,
но это пример того,
какой примерно инструмент хотелось бы.
Хочется использовать какой-то код типа такого:
#!/bin/bashset -x
set -edeclare -r fileTmpA="/tmp/$( basename "${0}" )_A"
declare -r fileTmpB="/tmp/$( basename "${0}" )_B"
trap "rm '${fileTmpA}' '${fileTmpB}'" EXIT HUP INT TERM
################################################
function fillDictFromFile {
local -r fileName
local -A dictionary
while read string ; do
key="$( echo "${string}" | md5sum | cut --delim=' ' --field 1 )"
dictionary["${key}"]="${value}"
done <<< "$( cat "${fileName}" )"
return dictionary
}
echo -ne "0000\n1111\n" > "${fileTmpA}"
echo -ne "2222\n3333\n" > "${fileTmpB}"declare -A dictionary_A="$( fillDictFromFile "${fileTmpA}" )"
declare -A dictionary_B="$( fillDictFromFile "${fileTmpB}" )"
################################################
set +x
echo "________________________________________________"
for key in "${!dictionary_A[@]}" "${!dictionary_B[@]}" ; do
echo "Have key: ${key}"
doneКак делают? Perl, C и т.д. :) :) - да, я знаю их и др. А вот есть ли что-то для Shell?
> Bash так не умеет,
#!/bin/bashset -e
set -xfileTmpA="/tmp/$(basename $0)_A"
fileTmpB="/tmp/$(basename $0)_B"trap "rm $fileTmpA $fileTmpB" EXIT HUP INT TERM
################################################
function fDFF {
local i=0;
local -a dict=();for string in $(cat $1)
do
key=$(echo $string | md5sum | cut -d' ' -f1);
dict[$i]=$key;
((i++));
done;
echo ${dict[@]}
}echo -ne "0000\n1111" > $fileTmpA;
echo -ne "2222\n3333" > $fileTmpB;declare -a dictionary_A=($(fDFF $fileTmpA));
declare -a dictionary_B=($(fDFF $fileTmpB));################################################
echo "________________________________________________"
for key in "${dictionary_A[@]}" "${dictionary_B[@]}" ;
do
echo "Have key: ${key}"
done
________________________________
Have key: 4c3cbcadf7b8a9ae2932afc00560a0d6
Have key: 1f18348f32c9a4694f16426798937ae2
Have key: 9dc23e23a84232dd4e5919863161285c
Have key: 4fb7e693a03d73ab460a97e3f92fd20b
Если в строках будут пробелы, спец. символы и инструкции Shell или esc последовательности - оно сломается ведь?Интересно словарь "вернуть" из функции. Не просто массив,
declare -a ARRAY=(E1 E2 …)
а словарь
declare -A ARRAY=([X]=E1 [Y]=E2 …)Если "${dict[@]}" разворачивается как независимые строки, по одной строке на элемент, то приставка echo склеивает всё в одну строку. Потеря информации.
Можно пытаться расставлять экраны и кавычки/апострофы, но не знаю простого и читаемого способа сделать это. Хорошо бы ещё и быстрого, т.к. вызов sed и т.п. довольно долго происходит.
> Хорошо бы ещё и быстрого, т.к. вызов sed и т.п. довольно долго происходит.Хе... Вот те задачка на ассоциативные массивы:
Заменить в тексте все буквы русского алфавита на схожие по-написанию латинские. Только bash.
#!/bin/bash
RUS_CAP=(А В Е К М Н О Р С Т Х)
LAT_CAP=(A B E K M H O P C T X)RUS_LET=(а е о р с у х)
LAT_LET=(a e o p c y x)Текст:
http://vojnaimir.ru/files/book1.txt.zip
http://vojnaimir.ru/files/book2.txt.zip$ unzip -c book1.txt.zip | iconv -f cp1251 -t utf8 > BOOK.txt
$ unzip -c book2.txt.zip | iconv -f cp1251 -t utf8 >> BOOK.txt$ time cat BOOK.txt | convert.sh;
и показываешь тут время.
---
В гугл не подсматривать.----
Ну чтоб сразу расстроился :-P
$ time cat BOOK.txt | sed 'y/АВЕКМНОРСТХаеорсух/ABEKMHOPCTXaeopcyx/' > bebebe
real 0m1.593s
user 0m1.565s
sys 0m0.036s
>[оверквотинг удален]
> последовательности - оно сломается ведь?
> Интересно словарь "вернуть" из функции. Не просто массив,
> declare -a ARRAY=(E1 E2 …)
> а словарь
> declare -A ARRAY=([X]=E1 [Y]=E2 …)
> Если "${dict[@]}" разворачивается как независимые строки, по одной строке на элемент, то
> приставка echo склеивает всё в одну строку. Потеря информации.
> Можно пытаться расставлять экраны и кавычки/апострофы, но не знаю простого и читаемого
> способа сделать это. Хорошо бы ещё и быстрого, т.к. вызов sed
> и т.п. довольно долго происходит.\r добавляешь в конец каждого элемента, и echo нарисует как надо..