BASH (вопросы и ответы.)
Модераторы: /dev/random, Модераторы разделов
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
BASH
В процессе написания скрипта у меня всё больше и больше увеличивается число используемых массивов, которые между собой тесно связаны. В связи с этим задался вопросом, а есть ли возможность реализации структур в баше, как на сях, например? Или что-то похожее по свойствам.
Bash - массивы и структуры
Сравнение чисел при помощи echo и bc (ver1)
Сравнение чисел при помощи echo и bc (ver2)
Сравнение чисел при помощи echo и bc (ver3)
Арифметические операции при помощи echo и bc
Арифметические операции при помощи echo и awk
Как из Шестнадцатиричного числа получить символ ASCII
Bash - массивы и структуры
Сравнение чисел при помощи echo и bc (ver1)
Сравнение чисел при помощи echo и bc (ver2)
Сравнение чисел при помощи echo и bc (ver3)
Арифметические операции при помощи echo и bc
Арифметические операции при помощи echo и awk
Как из Шестнадцатиричного числа получить символ ASCII
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Бывший модератор
- Сообщения: 8259
- Статус: Маньяк
- ОС: Arch, Fedora, Ubuntu
Re: BASH
Нет.Naruto-kun писал(а): ↑04.05.2009 17:47есть ли возможность реализации структур в баше, как на сях, например? Или что-то похожее по свойствам.
-
- Бывший модератор
- Сообщения: 8259
- Статус: Маньяк
- ОС: Arch, Fedora, Ubuntu
Re: BASH
Аналогичный, кстати, вопрос: http://www.experts-exchange.com/Programmin...Q_20890007.html - разумеется это подобие "структуры" применимо к любому языку, поскольку со стороны языка ничего не требуется.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
Naruto-kun писал(а): ↑04.05.2009 17:47В процессе написания скрипта у меня всё больше и больше увеличивается число используемых массивов, которые между собой тесно связаны.
ИМХО надо другой язык использовать в таком случае...
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
drBatty писал(а): ↑04.05.2009 18:05Naruto-kun писал(а): ↑04.05.2009 17:47В процессе написания скрипта у меня всё больше и больше увеличивается число используемых массивов, которые между собой тесно связаны.
ИМХО надо другой язык использовать в таком случае...
По некоторым причинам не могу, потому и задал этот вопрос. Если бы можно было использовать другой язык, тему бы не создавал.
UP Нашёл выход из положения без использования структур. Но вопрос всё равно оставлю, но уже для себя интересно.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: BASH
Нуу... тиаретиццки... :)
В баше есть массивы. При достаточно большом желании их можно использовать как структуры:
В баше есть массивы. При достаточно большом желании их можно использовать как структуры:
Код: Выделить всё
X=0
Y=1
Z=2
POINT[$X]=5
POINT[$Y]=10
POINT[$Z]=15
echo ${POINT[$X]}, ${POINT[$Y]}, ${POINT[$Z]}
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
Ясно. Просто, по поводу массивов я знаю и во всю их использую, а вот как со структурами быть, не знал.
Возник ещё один вопрос, новую тему создавать не стал. Задам здесь же. Есть ли в баше возможность работать с данными типа float или double?
Просто у меня есть массив чисел типа: 11,2; 1,45; 1094,42; и тд. В скрипте мне их нужно сравнивать (что больше, что меньше). И исходя из условий вычитать одно из другого. Я пробовал так:
На что он конечно ругался:
Возник ещё один вопрос, новую тему создавать не стал. Задам здесь же. Есть ли в баше возможность работать с данными типа float или double?
Просто у меня есть массив чисел типа: 11,2; 1,45; 1094,42; и тд. В скрипте мне их нужно сравнивать (что больше, что меньше). И исходя из условий вычитать одно из другого. Я пробовал так:
Код: Выделить всё
a[0]=1
a[1]=1,2
if [ ${a[1]} -gt {a[0]} ]; then
let "a[1] = ((a[1]-a[0]))"
fi
На что он конечно ругался:
Код: Выделить всё
./test.sh: line 10: [: 1,2: integer expression expected
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
есть bcNaruto-kun писал(а): ↑05.05.2009 16:57Просто у меня например есть массив чисел типа: 11,2; 1,45; 1094,42; и тд. В скрипте мне их нужно сравнивать
Код: Выделить всё
drb ~$ echo "5<6" | bc
1
drb ~$ echo "100>256" | bc
0
с дробными числами он тоже может.
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
Попробовал, то что вы посоветовали. Выдал ошибку.
К тому же вы указали, только пример сравнения. А как быть с арифметическими операциями вроде сложения или вычитания?
Код: Выделить всё
syntax error on line 1, teletype
К тому же вы указали, только пример сравнения. А как быть с арифметическими операциями вроде сложения или вычитания?
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
Naruto-kun писал(а): ↑05.05.2009 17:21ак быть с арифметическими операциями вроде сложения или вычитания?
Код: Выделить всё
echo "2+2*2" | bc
6
есть в конце концов man bc!
ЗЫЖ как можно запускать непонятные команды?! может я вам знаменитый однострок на перле сую!
ЗЗЫЖ кстати возможности bc этим не исчерпываются, там есть функции(свои и стандартные, вроде синусов), переменные, разная степень точности, выбор системы счисления(хоть 13иричная!) и прочее. Незаменимая команда для работы с числами.
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
Ну судя по содержимому строки не очень похоже на знаменитый однострок на пёрле. C манами и хелпами же на работе - проблема. На работе не полноценный линух, а что-то вроде эмулятора терминала в винде. Не знаю почему, но манов тут и в помине нет. И собственно поэтому же я не боюсь никаких однострок, в крайнем случае эмулятор всегда могу ребутнуть, либо в само крайнем случае пересобрать. Приду домой почитаю на домашней тачке маны по bc.
PS. По поводу ошибки я так пока и не понял, в чём косяк. И что удиветильно ругается именно на операции сравнения, на арифметические операции не ругается.
PS. По поводу ошибки я так пока и не понял, в чём косяк. И что удиветильно ругается именно на операции сравнения, на арифметические операции не ругается.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
может bc тоже какой-то не полноценный. а если "5 < 2 * 2" ?Naruto-kun писал(а): ↑05.05.2009 17:36И что удиветильно ругается именно на операции сравнения, на арифметические операции не ругается.
-
- Сообщения: 1685
- ОС: SuSe 10.2
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
drBatty писал(а): ↑05.05.2009 17:41может bc тоже какой-то не полноценный. а если "5 < 2 * 2" ?Naruto-kun писал(а): ↑05.05.2009 17:36И что удиветильно ругается именно на операции сравнения, на арифметические операции не ругается.
Всё равно ошибку выдаёт.
Именно баш.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: BASH
>>Именно баш.
да?.. но...
>>В процессе написания скрипта у меня всё больше и больше увеличивается число используемых массивов
Сдается мне вы ошиблись с выбором средства реализации...
да?.. но...
>>В процессе написания скрипта у меня всё больше и больше увеличивается число используемых массивов
Сдается мне вы ошиблись с выбором средства реализации...
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
дык попробуйте вычитание, и отрежьте первый символ, если "-" то первое число меньше второго. Проверять на равенство float ни в коем случае нельзя! Это как i++ + ++i в сях - руки кодерам отрывать за такое надо...
я уже говорил, но почему-то надо... выше пост про это...
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
дык попробуйте вычитание, и отрежьте первый символ, если "-" то первое число меньше второго. Проверять на равенство float ни в коем случае нельзя! Это как i++ + ++i в сях - руки кодерам отрывать за такое надо...
Хмм, попробую. Других идей у меня пока всё равно не появилось.
PS. Протестил bc дома, работает как часы. В очередной раз убедился в ущербности эмулятора у себя на работе.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
Нашёл выход из положения:
В результате выдаёт, то что нужно:
PS. Всем, кто так или иначе помог, спасибо.
Код: Выделить всё
x=2.4
y=1.2
echo "$x $y" | awk '{if ($1 >= $2) print 1; else print 0}'
echo "$x $y" | awk '{print $1 + $2}'
В результате выдаёт, то что нужно:
Код: Выделить всё
1
3.6
PS. Всем, кто так или иначе помог, спасибо.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
Хмм, возник ещё один вопрос. Есть скрипт. В нём, в начале из файла все данные загоняются в массивы. У меня это сделано так:
Сделано так, потому что в файле между данными в строке разное число пробелов, а echo же насколько я понял и проверил на практике сводит всё к одному пробелу между данными. Хотелось бы узнать можно ли как то этот процесс ускорить. Может это возможно сделать быстрее?
PS. В данный момент файлы могут состоять из 1000 и более строк и процесс перегонки данных из файла в массивы занимает очень много времени.
Код: Выделить всё
i=0; while read line
do
ddate[$i]=`echo $line | cut -d" " -f1`
type[$i]=`echo $line | cut -d" " -f2`
id[$i]=`echo $line | cut -d" " -f3`
name[$i]=`echo $line | cut -d" " -f4`
oper[$i]=`echo $line | cut -d" " -f5`
let "i+=1"
done < ${LST}
Сделано так, потому что в файле между данными в строке разное число пробелов, а echo же насколько я понял и проверил на практике сводит всё к одному пробелу между данными. Хотелось бы узнать можно ли как то этот процесс ускорить. Может это возможно сделать быстрее?
PS. В данный момент файлы могут состоять из 1000 и более строк и процесс перегонки данных из файла в массивы занимает очень много времени.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: BASH
Код: Выделить всё
while read ddate[$i] type[$i] id[$i] name[$i] oper[$i]; do ...
не покатит? если нет ....
Код: Выделить всё
while read a b c d e; do
ddate[$i] = a
.....
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
Спасибо за
Оказалось в разы быстрее моего варианта. Спасибо большое.
PS. Раз уже так оказалось, может и здесь тогда подскажете как повысить скорость работы. Здесь основной алгоритм в следующем:
1) Сравниваем текущий счёт и предыдущий. (Начинаем это делать со 2-ого элемента)
2) Если счета окажутся одни и те же записываем сумму предыдущего счёта в счёт текущего.(Начинаем это делать со 2-ого элемента)
3) Проверяем больше или равно ли на счёту, чем сумма комиссии. (с помощью echo и awk, так как bc на работе у меня урезанный какой-то)
4) Если результат сравнения = 1 (В данном случае это будет означать, что средств достаточно), то:
4.1) Вычитаем из суммы счёта сумму комиссии, перед этим заменив в суммах запятые на точки ( У меня связка echo и awk в операции вычетания с запятыми почему то не не хочет работать).
4.2) Записываем изменённую сумму и заменяем обратно точку на запятую.
4.3) Выставляем право на съём = 1.
5) Если результат сравнения = 0, то выставляем право на съём = 0.
У меня реализовано так:
Код: Выделить всё
while read ddate[$i] type[$i] id[$i] name[$i] oper[$i]; do ...
Оказалось в разы быстрее моего варианта. Спасибо большое.
PS. Раз уже так оказалось, может и здесь тогда подскажете как повысить скорость работы. Здесь основной алгоритм в следующем:
1) Сравниваем текущий счёт и предыдущий. (Начинаем это делать со 2-ого элемента)
2) Если счета окажутся одни и те же записываем сумму предыдущего счёта в счёт текущего.(Начинаем это делать со 2-ого элемента)
3) Проверяем больше или равно ли на счёту, чем сумма комиссии. (с помощью echo и awk, так как bc на работе у меня урезанный какой-то)
4) Если результат сравнения = 1 (В данном случае это будет означать, что средств достаточно), то:
4.1) Вычитаем из суммы счёта сумму комиссии, перед этим заменив в суммах запятые на точки ( У меня связка echo и awk в операции вычетания с запятыми почему то не не хочет работать).
4.2) Записываем изменённую сумму и заменяем обратно точку на запятую.
4.3) Выставляем право на съём = 1.
5) Если результат сравнения = 0, то выставляем право на съём = 0.
У меня реализовано так:
Код: Выделить всё
...
n=$i; i=0; # n - количество элементов.
while [ $i -lt $n ]
do
if [ $i -gt 0 ]; then
let "j = ((i-1))"
if [ ${panCount[$i]} -eq ${panCount[$j]} ]; then
panSum810[$i]=${panSum810[$j]}
fi
fi
check=`echo "${panSum810[$i]} ${KomissSum810[$i]}" | awk '{if ($1 >= $2) print 1; else print 0}'`
if [ $check -eq 1 ]; then
panSum810_float=`echo ${panSum810[$i]} | sed -e 's/,/./'`
komissSum810_float=`echo ${KomissSum810[$i]} | sed -e 's/,/./'`
panSum810_float=`echo "$panSum810_float $komissSum810_float" | awk '{print $1 - $2}'`
panSum810[$i]=`echo $panSum810_float | sed -e 's/\./,/'`
operation_rull[i]=1
elif [ $check -ne 1 ]; then
operation_rull[i]=0
fi
let "i+=1"
done
...
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: BASH
не понятно. т.е. в строке могут быть пропущенные поля?
ну, перед парсингом вставьте между двумя подряд идущими пробелами что-нибудь, что вам не помешает. например, «""»:
sed 's/ / "" /g'
в любом случае, будет быстрее читать одной встроенной командой read, нежели запуском пяти процессов echo и пяти процессов cut.
p.s. пока писал, вышло, что писал напрасно. оказывается, никаких скрытых смыслов и не было. вот так всегда… не обращаешь внимания на ник.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
sash-kan писал(а): ↑14.05.2009 16:36не понятно. т.е. в строке могут быть пропущенные поля?
ну, перед парсингом вставьте между двумя подряд идущими пробелами что-нибудь, что вам не помешает. например, «""»:
sed 's/ / "" /g'
в любом случае, будет быстрее читать одной встроенной командой read, нежели запуском пяти процессов echo и пяти процессов cut.
p.s. пока писал, вышло, что писал напрасно. оказывается, никаких скрытых смыслов и не было. вот так всегда… не обращаешь внимания на ник.
Ну, почему же напрасно, приму к сведению. Лишних советов не бывает.
PS. Последний вопрос, описанный в предыдущем посте пока до сих пор не решён. Скорость выполнения оставляет желать лучшего. Так, что буду рад любым предложениям.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: BASH
ускорить немножко, конечно можно.
например, убрав вызовы sed, а замену точка/запятая возложив на awk, раз всё одно он вызывается.
но если время критично, возможно, имеет смысл сложить данные в базу данных.
например, убрав вызовы sed, а замену точка/запятая возложив на awk, раз всё одно он вызывается.
но если время критично, возможно, имеет смысл сложить данные в базу данных.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
ИМХО либо sed, либо awk, либо bash...
-
- Сообщения: 228
- Статус: небритый гентушник
- ОС: Gentoo(PC)/easypeasy(Netbook)
Re: BASH
ускорить немножко, конечно можно.
например, убрав вызовы sed, а замену точка/запятая возложив на awk, раз всё одно он вызывается.
но если время критично, возможно, имеет смысл сложить данные в базу данных.
Спасибо, попробую. Правда, не совсем понятно как с помощью делать замены, подобные sed. Ладно погуглю. Кстати обнаружил странность для себя, в сравнении чисел. Вот например:
Код: Выделить всё
a=4,06
b=10
echo "$a $b" | awk '{if ($1 >= $2) print 1; else print 0}'
Здесь он, по условию должен выдать 0. Но почему-то выдаёт 1. Не могу понять причины.
UP: Кажется, что вся проблема была в запятой. Поставил вместо запятой точку и он выдал 0, как и должно быть.
Компьютер позволяет решать все те проблемы, которые до изобретения компьютера не существовали.
Если на вопрос ни кто не знает ответа, то пора читать описание.
Если на вопрос ни кто не знает ответа, то пора читать описание.
-
- Сообщения: 694
Re: BASH
У меня есть строка состоящая из двух шестнадцатиричных цифр.
Требуется получить символ ASCII-кодом которого является значение переменной A.
Чем это делается?
=========
Кажется сам нашёл:
========
Ещё один вариант. От drBatty. BASH
Мне он кажется более универсальным: echo скорее всего на целевой платформе будет, а printf - неизвестно:
Код: Выделить всё
A="FD"
Требуется получить символ ASCII-кодом которого является значение переменной A.
Чем это делается?
=========
Кажется сам нашёл:
Код: Выделить всё
A="31"
printf "\x$A\n"
1
========
Ещё один вариант. От drBatty. BASH
Мне он кажется более универсальным: echo скорее всего на целевой платформе будет, а printf - неизвестно:
Код: Выделить всё
А="31"
echo -e "\x$A"
1
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
угу. printf универсальное средство. хотя используете вы его тут совсем весело

тут что угодно можно поставить
Код: Выделить всё
sed "s/.*/\x$A/;q" ~/.bashrc
-
- Сообщения: 694
Re: BASH
А что не так?

Я читаю данные из базы (mysql-клиентом), там поле blob с массивом значений.
Каждый байт - две шестнадцатеричные цифры. Нужно преобразовать в строку символов.
Вот я read'ом читаю по 2 символа и озадачился как полученный байт в виде двух цифр преобразовать в символ.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: BASH
ну у вас как-бы сказать...
на самом деле, вы получаете строку из строки, а потом строку считаете тоже строкой, только из шестнадцатеричных символов

А как вы эти BLOB'ы читаете? у меня почему-то получаются обычные символы...