mironov_orig 09.08.2011 12:20
Tips & tricks — shell-штучки-дрючки
Выкидываю заметку из черновиков как есть.Для начала оговоримся, что мы имеем дело именно с башем — со скриптами под свои нужды, автоматизацией рутинных действий и т.п. никаких загрузочных скриптов и прочего restricted posix shell.
Если вам не нужна переносимость (между ОС (*nix, *BSD, Solaris, etc) и шелами (sh, dash, bash, zsh, tcsh, ksh etc)), вы пишите не скрипт инициализации для SysVinit а просто скрипт для личных и не очень нужд, имеет смысл не ограничивать себя рамками posix-совместимого шела. Нижеследующие советы предлагаются к прочтению всем, кто не читал man bash или соответствующую главу POSIX'a.
Сравнения
1 |
|
1. внутри [[ ]] не действует «разбиение на слова» (word spliting) ⇒ мы спокойно можем использовать переменные без «заковычивания», если в строке есть пробел, ничего страшного не случится.
2. спецсимволы *, ? и [ воспринимаются как обычные символы (никакого глобинга)
3. всё остальное действует
Арифметика
1 |
|
- унарные - и +
- ++var, --var
- var++, var--
- ! и ~ логическое и побитовое отрицание
- % - остаток от деления
- << >> побитовые сдвиги
- =, >=, <=
- ==, !=
- &, |, ^ побитовые и, или, исключающее или
- &&, || логические и, или
- операции через запятую
- expr?expr:expr
- поддержка восьми- и шестнадцатибитныз чисел(в формате с ведущим нулём)
- поддержка чисел в системах счисления с основанием от 2 до 64 (base#n)
Если вам нужно, в баше есть арифметический цикл for
1 |
|
Дополнительно
В баше есть такая штука
1 |
|
1. Использование значения по-умолчанию
1 |
|
2. Присвоение значения по умолчанию
1 |
|
3. Отобразить ошибку, если переменная не существует или пуста
1 |
unset param
|
1 |
|
5. Вывод подстроки
1 |
|
8. Длина строки
1 |
${#param} #длина строки
|
9. Удаление префикса
1 |
${param%suffix} #удаление наименьшего постфикса
|
1 |
${param/pattern/string} # обрабатывается только первое вхождение
|
12. Изменение регистра
1 |
|
Литература
1. man bash2. Shell Command Language
Например.. у тебя есть страница в html, которую нужно распарсить и оставить только
всё остальное удалить. Подобный, работающий скрипт на питоне мне написал NVBN.
from BeautifulSoup import BeautifulSoup
import urllib, sys
def parse(value, valid_tags, valid_attrs):
valid_tags = valid_tags.split()
valid_attrs = valid_attrs.split()
soup = BeautifulSoup(value)
for tag in soup.findAll(True):
if tag.name not in valid_tags:
tag.hidden = True
if tag.name == 'script':
tag.content = ''
else:
tag.attrs = [(attr, val) for attr, val in tag.attrs if attr in valid_attrs]
return soup.renderContents()
if __name__ == '__main__':
data = urllib.urlopen(sys.argv[1]).read()
print parse(data, 'tr td th table body head html a', 'href rowspan colspan').replace('head>', """head>
'
""")
А ты можешь сделать такое на баше?
tr td th table body head html a href rowspan colspan
всё остальное удалить. Подобный, работающий скрипт на питоне мне написал NVBN.
from BeautifulSoup import BeautifulSoup
import urllib, sys
def parse(value, valid_tags, valid_attrs):
valid_tags = valid_tags.split()
valid_attrs = valid_attrs.split()
soup = BeautifulSoup(value)
for tag in soup.findAll(True):
if tag.name not in valid_tags:
tag.hidden = True
if tag.name == 'script':
tag.content = ''
else:
tag.attrs = [(attr, val) for attr, val in tag.attrs if attr in valid_attrs]
return soup.renderContents()
if __name__ == '__main__':
data = urllib.urlopen(sys.argv[1]).read()
print parse(data, 'tr td th table body head html a', 'href rowspan colspan').replace('head>', """head>
'
""")
А ты можешь сделать такое на баше?
Можно, но для подобного лучше perl|python с какой-нить красивой либой
Pisal na proshloj rabote... V principe - nichego slozhnogo, no dovol'no neuniversal'no i mnogoslovno.
Lenivo eshe raz pisat'.
Lenivo eshe raz pisat'.
lxml.html имхо както удачнее чтоли, или привычнее, ну вы на него посмотрите, под питоном самая лучшая либа.
Под С вообще самая лучшая =)
Под С вообще самая лучшая =)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
['html', 'head', 'meta', 'link', 'script', 'title', 'body', 'div', 'ol', 'li', 'a', 'span', 'h', 'img', 'br', 'table', 'tr', 'td', 'ul', 'form', 'input', 'noscript']
Не на баше, но регуляркам же все-равно =)
Ты не так понял задачу. Надо оставить не только сами теги, но и то, что между ними =)
... и оставить только
tr td th table body head html a href rowspan colspan
всё остальное удалить.
tr td th table body head html a href rowspan colspan
всё остальное удалить.
А в чем же тогда профит? =)
PS: в своем решении профита тоже не нашел.
это перевод, знаменитого ABSG. К тому же, наверняка, несвежий. Рекоммендую читать в оригинале.
если верить номеру ревизии в ссылке на странице, это перевод версии ABS 1.8 (15 May 2003 14:52) - еще тот труп. Текущая версия 6.3 от 2 мая 2011
вот кстати ABSG на фрешмите:
http://freshmeat.net/projects/advancedbashscriptingguide
вот кстати ABSG на фрешмите:
http://freshmeat.net/projects/advancedbashscriptingguide
за 9 лет-то да, появилось много новых фич, о которых стоило бы знать.
Вот и напишите об этом (http://welinux.ru/post/6369/), мне этого гайда за глаза хватает, и всё работает. Но вот обновлений bash помню по пальцам... чтобы что-то такое координальное... не, не видел.
Дык не в гайдах дело. однократное полное прочтение man bash покроет 90% потребностей, только вот никто маны особо не читает.
я бы сказал не каждый пользователь догадывается о ее существовании. для гуевых утилит это явление особо распространено.
я не призываю никого читать ман баш от корки до корки. ABSG скорее сборник рецептов. я к нему обращаюсь по мере возникновения вопросов. все тобой описанное в статье там приводится с примерами.
Оч хорошо!
и с какой это радости я должен забывать про $((...)), если он мне дает результат арифметической операции?
Маэстро подтянулся ☺ лучше б ты написал статью )
Говорил же, что черновик, на мой взгляд в основном для аривметических операций лучше let, но если нужно inline что-то посчитать-подставить, то $(()) безусловно лучше.
Говорил же, что черновик, на мой взгляд в основном для аривметических операций лучше let, но если нужно inline что-то посчитать-подставить, то $(()) безусловно лучше.
> 1. внутри [[ ]] не действует «разбиение на слова» (word spliting) ⇒ мы спокойно можем использовать переменные без «заковычивания», если в строке есть пробел, ничего страшного не случится.
а если внутри == или && ?
а если внутри == или && ?
Всё равно всё будет путём и эта часть воспримится именно как строка для сравнения.
С примерами если можно.