1599937282669.jpg68 Кб, 767x1000
awk /awk/ 3394016 В конец треда | Веб
си оказался для меня пока что слишком сложным, а баш слишком простым, слишком целочисленным (это можно обойти костылями но всё-таки) и без директивы include из-за чего там надо для читабельного кода городить костыль из main "$@" под чудовищной простынёй из функций.

а вот у awk и принцип работы необычный, и синтаксис максимально похож на сишный, и реализацию с логикой можно разнести по разным файлам. ну и плюс это один из языков которым больше 45 лет и которые до сих пор активно используются, по крайней мере я при поиске ответов на стековерфлоу в 90% случаев вижу ванлайнеры на awk.

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

самый лучший гайд по основам который я видел https://youtu.be/E5aQxIdjT0M?t=651
классический учебник https://rutracker.org/forum/viewtopic.php?t=6412544 но язык там тяжеловат, может мне не хватает знания языка, может просто выражения старомодные.
примеры разных алгоритмов https://www.youtube.com/watch?v=4UGLsRYDfo8

а ещё в awk можно превращать любую нечитаемую awk-хуйню из ответов со стековерфлоу в нормальный понятный код если запустить её с awk -o- 'нечитаемый_ванлайнер'
2 3394029
Так и не осилил это и не понимаю, зачем оно, когда есть перл. Там тебе и программы на много файлов писать с АРХИТЕКТУРОЙ и неймспейсами, и ванлайнеры, умеющие больше чем sed и awk вместе взятые. Разве только в бизибокс перл не засунешь, но на дженерик x86 машине вообще похуй.
3 3394032
>>4029
на опенврт перл весит больше мегабайта https://openwrt.org/packages/pkgdata/perl плюс авк есть вообще везде в том числе на роутерах, а вот для перла надо парсить /etc/os-release для выяснения на какой системе запустили скрипт, каким пакетным менеджером его установить, что делать если это старый роутер, всё место уже занял болвановский запрет с хостлистами и перл ставить вообще некуда.

ну и честно говоря я не осилил перловский синтаксис, мне лень в него вникать когда есть авк с сишным синтаксисом. плюс авк не менялся с 1994 года и любой нагугленный ванлайнер написанный за последние 30 лет будет работать так же как и когда его писали.
4 3394033
>>4016 (OP)

>и без директивы include


help source
5 3394035
>>4032

>опенврт


Так и думал.

>надо парсить /etc/os-release для выяснения на какой системе запустили скрипт, каким пакетным менеджером его установить


Зачем?

>любой нагугленный ванлайнер написанный за последние 30 лет будет работать так же как и когда его писали.


Для перла тоже справедливо, там обратную совместимость десятилетиями тянут с недавнего времени стало хуже, но шансы нарваться на протухший код всё ещё ничтожны.
6 3394041
>>4016 (OP)
Bash-холопы как всегда соснули у Powershell-бояр.
7 3394045
>>4035
/etc/os-release надо парсить потому что на разных системах ставить пакеты надо разными пакетными менеджерами и я не придумал ничего лучше чем выдернуть инфу через cat /etc/os-release | grep -E -i '^ID=' | sed 's/ID=//g' | sed 's/\"//g' и сделать case-esac для всех популярных дистров включая опенврт. но это в любом случае плохое решение, скрипт должен максимально полагаться на то что уже и так везде предустановлено.
1692757690979.gif414 Кб, 480x238
8 3394047
9 3394055
>>4016 (OP)

>си оказался для меня пока что слишком сложным, а баш слишком простым


Разве awk не годится только на то чтобы вытащить кусок текста из потока вывода или файла?
Как его можно сравнивать с сишкой и даже с башем, которые вполне полноценные языки?
10 3394056
а нахуй это нужно если есть питон, дебичи блять.
11 3394058
>>4056
Ну в данном случае дебич здесь только ты, если не понимаешь что питон вообще под такие задачи не заточен.
12 3394061
>>4045
Какие пакеты надо ставить в перл, чтобы написать на нём то же самое, что ты будешь писать на awk, куда ты никаких пакетов ставить, насколько я понимаю, не планируешь?
Это раз. Два - клиент к cpan идёт в комплекте со стандартной либой.
Либо я тебя не понял, либо аргумент, мягко говоря, сомнительный.

>>4056
Покажи однострочник на питухоне.
13 3394063
>>4055
Он полный по Тьюрингу.
14 3394064
>>4016 (OP)
Лучший учебник - это жизнь. После того как три дня выясняешь почему абсолютно одинаковые скрипты на одинаковых ос ведут себя по разному просто потому что какая-то либа заменила mawk на gawk, раз и навсегда переходишь на питон.
15 3394065
>>4055
по ссылке что я давал есть веб-сервер написанный на awk. а вытащить можно и грепом. awk в принципе такой же полноценный язык, по крайней мере по словам Кернигана. драйвера на нём писать не получится, но по такому принципу и питон с джавой можно из полноценных исключить. циклы, условия, ассоциативные массивы там есть, что ещё тебе надо чтобы признать полноценным языком? и главное зачем, свои задачи он делает и делает хорошо.
изображение.png15 Кб, 1775x103
16 3394074
>>4061

>однострочник на питухоне


Пистон это перлодрочество, конечно, не поощряет, но и не запрещает. Пиши себе свои однострочники.
17 3394077
>>4061
не, пакеты в перл не надо ставить, ставить надо сам перл, на опенврт его нет и нинужна, для большинства роутеров которые на руках у людей в рф он слишком тяжёлый и на эти роутеры не всегда даже запрет с nfq и хостлистами удаётся впихнуть. более того, я погуглил и оказалось что например на федоре предустановлен питон но не предустановлен перл https://www.cyberciti.biz/faq/install-perl-in-fedora-linux-using-dnf-command/ то есть для баш-скрипта с использованием перла надо городить костыль который будет проверять что за система, как проверить что перл установлен, как его установить - много мороки.

я делал баш-портянку которая автоматически обновляет настройки обхода блокировки ютуба (осенью методы блокировки менялись почти каждый день и я заебался каждый день после работы прогонять блокчек вручную) и надо было вытащить адрес GGC чтобы воткнуть в запретовский блокчек, на стековерфлоу нашёл ванлайнер на перле, и выяснилось что он без пакета https://openwrt.org/packages/pkgdata/perl не работает. мне места на роутере хватило конечно, но у меня роутер сильно лучше чем у большинства. а вот awk предустановлен везде и адрес выдёргивает через curl -s "https://www.youtube.com/watch?v=eZD5z7MTvJY" | awk '$1 ~ /googlevideo/ { print substr($0,RSTART+26,RLENGTH+37) }'
18 3394090
>>4074
Ты же понимаешь, что у тебя на картинке полный пиздец?
19 3394093
>>4090

> | grep -E -i '^ID=' | sed 's/ID=//g' | sed 's/\"//g' - это не пиздец


> startswith и replace - это пиздец


Держи в курсе
20 3394103
>>4093
Да, вот только всё это очень здорово нет, ведь это уродливая ооп.дрисня(), пока тебе надо достать простенький паттерн из файлика с парами ключ="значение" и вся твоя логика влазит в один СТЕЙТМЕНТ. Для чего посложнее ты будешь писать мусорный скрипт с убогой императивщиной внутри, которая всё равно использует перловые регулярки.
21 3394153
>>4093
я эти ванлайнеры стырил со стековерфлоу и тоже плевался с синтаксиса sed, но он вроде ещё древнее чем awk. сейчас я бы на awk сделал более читаемый код типа такого

os_id=$(cat /etc/os-release | awk '
BEGIN {
FS = "="
}

/^ID=/ {
gsub("\"","")
print $2
}
')
22 3394169
>>4103

>Для чего посложнее ты будешь писать мусорный скрипт


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

>>4153
Ты как то сразу забыл про условие однострочника.
23 3394173
>>4169

>Для чего посложнее ты в любом случае будешь писать мусорный скрипт.


Ты будешь писать вместе с другими зумерами-питухоноблядками. Я буду только в исключительных случаях. У тебя же таким случаем будет каждый второй.
24 3394191
>>4169
ну его можно и в однострочник сжать при желании
os_id=$(cat /etc/os-release | awk 'BEGIN {FS = "="} /^ID=/ {gsub("\"",""); print $2}')
ты же выше писал что у sed синтаксис нечитаемый, я его сделал максимально читаемым. но в принципе он и в однострочном виде выглядит лучше чем sed. да и на питоне норм, но питон не везде есть в отличие от awk и в питоновском однострочнике стоит ещё кавычки удалить потому что в некоторых дистрах они есть https://github.com/which-distro/os-release/blob/main/openwrt/23.05.3 и это неудобно потом в case-esac пихать.
25 3394196
вообще и кат конечно не нужен, это всё встроенными средствами авк делается
awk 'BEGIN {FS = "="} /^ID=/ {gsub("\"",""); print $2}' /etc/os-release
26 3394216
>>4191
Да я больше про то, что читаемость - дело субъективное, зависит от опыта.

Немного эксплицирую тезис, чтобы не раздувать холивар. Интерактивный REPL и скриптование - сильно разные задачи.
REPL - это про стрелка вверх, дописать хвост, повторить итерацию, пока не получишь результат.
Скриптование - про повторяемость и переносимость.
Императивные языки для REPL действительно не годятся. ipython - говно, xonsh - большее говно, единственный живой ООП репл - это powershell, и то он опп только на полшишечки. Все эти nushell, elvish, babashka, ammonite, oilsh, все живые альтернативные шеллы - функциональщина.
А вот когда речь идёт о скриптах - тут уже всё сильно зависит от задачи. Иногда можно скопировать соплю из REPL и оставить всё как есть. А иногда надо с нуля переписывать всё. И тут уже выбираешь инструмент по ситуации. Где-то это pure sh, где-то awk, где-то python, где-то бинарник на go.
27 3394223
>>4196
Тем временем:
perl -nswE 'say /"(.+)"/ if /^NAME=/' /etc/os-release
Да, да, я знаю - опенврт, все дела...
28 3394224
вообще я неправильно написал выше, код который достаёт адрес GGC через RSTART/RLENGTH не будет правильно работать если адреса имеют разную длину, а они как правило имеют, правильно будет выдёргивать адрес GGC вот так

unset GGC_ADDRESS
GGC_ADDRESS=$(curl -s "https://www.youtube.com/watch?v=eZD5z7MTvJY" | awk 'BEGIN {
RS="\\/"
i=0
}

$1 ~ /googlevideo.com/ {
array[$i]=sprintf( $0 )
i++
}

END {
print array[$i]
}
')
echo "GGC -> $GGC_ADDRESS"
29 3394230
>>4216

>ООП репл


Но зачем?
30 3394231
>>4196
Пистон через регулярочки:
python3 -c 'import re; print(re.search(r"^ID=(.*)", open("/etc/os-release").read(), re.M).group(1))'
изображение.png67 Кб, 821x578
31 3394236
>>4230

>Но зачем?


Много утилит теперь отдают структуры на stdout. Прост можно делать что-типа `.ID` вместо всех вот этих эзотерических заклинаний ИТТ.
32 3394243
>>4196
Короче чем на sh не сделать
. /etc/os-release; echo $ID
33 3394253
>>4236

>-json


Что это, зачем это? Что за утилиты, которые принудительно отдают тебе джсон и никак иначе? И почему это обязательно должно быть проблемой шелла?

echo '{"foo":2,"baz":{"qux":8}}' | perl -MJSON::XS -swE 'say $$_{foo} + $$_{baz}{qux} for decode_json(my $input = <>)'

Хотя я и не могу себе представить ситуацию, когда ты каждый день имеешь дело с тонной васянского говна, срущего исключительно джсоном в STDOUT.
34 3394282
>>4243
охуеть, это как работает? точка же это подстановка для текущего каталога, где команда читающая файл? как шелл понимает что символы до = это переменная которую можно вывести? по каким ключевым словам надо гуглить чтобы почитать документацию по таким трюкам?
35 3394335
>>3394313 →
в данном случае точка это команада source а не путь

мимо
36 3394336
37 3394421
>>4282
help .

>как шелл понимает что символы до = это переменная


У него такой синтаксис.
38 3394484
Никогда бы не подумал, что за пределами дома престарелых еще можно встретить фанатов перла.
39 3394493
>>4484
use Perl or die;
40 3394501
>>4484
Перл вполне себе жив на юникс системах и постоянно обновляется, просто о нем мало говорят т.к. ниша стала очень узкой, где-то на уровне между башем и awk. Но по умолчанию перл есть на любом линуксе. а вот питухон3 еще устанавливать надо.
41 3394508
https://ru.stackoverflow.com/questions/1607444/%D0%9A%D0%B0%D0%BA-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82-%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0-%D1%81%D1%82%D1%80%D0%BE%D0%BA-%D0%BF%D0%BE-%D0%B4%D0%BB%D0%B8%D0%BD%D0%B5-%D0%BD%D0%B0-%D1%87%D0%B8%D1%81%D1%82%D0%BE%D0%BC-awk

если кто-нибудь разбирается в awk ответьте на вопрос пожалуйста, я всю голову сломал. тут задать не могу, возвращает ошибку "присутствует слово из спам-листа".
42 3394518
>>4016 (OP)

>без директивы include


. "path/to/included.sh"
43 3394607
ладно, уже ответила добрая душа. пиздец у авк конечно жопоразрывающие тернарные операторы, теперь понимаю почему в книжке мартина написано избегать их любыми средствами.
44 3394661
>>4236
Вкатываюсь в девопс, постоянно замечаю в примерах awk и jq. Это стандартные тулзы для работы с json и текстом что-ли?
45 3394673
>>4661
Jq стандарт еще есть yq для пердолинга ямлов (для джейсонов тоже должно работать, тк любой корректный жсон это корректный ямл).
Awk юзается в простых однострочниках, обычно чтобы вырезать какой-то элемент из строки или типа того, гораздо стандартнее него - sed, grep, wc и так далее.
Выше уже говорилось, что если тебе нужен хоть сколько-то сложный скрипт, лучше написать его на питоне, а не городить шизофазическую баш портянку.
46 3394689
>>4607
Ты бы хоть подробнее писал с примерами, штоле, нам всем интересно.
47 3394736
а нахуй эти костыли, когда можно красиво в ямле и ансибле все сделать. дебичи блять.
48 3394765
>>4736
Долбоеб обосрался с питухоном и пошел на второй круг, кек.
49 3394860
>>4253

>должно быть проблемой


Это не проблема. Это преимущество.
50 3394861
>>4765

>обосрался


Обосрался тут только один шиз, который утверждал что питухон не умеет в однострочники.
1715177041944.png38 Кб, 818x160
51 3395209
>>4689
если вкратце то conditional expression это чрезвычайно изъёбистый способ сишных дидов записать if-then-else, да ещё и описанный английским языком времён молодого брежнева.

то есть при записи

expr1 ? expr2 : expr3

интерпретатор авк смотрит что у нас в expr1. если там переменная или элемент массива то он проверяет есть ли там чего. если там что-то есть и это что-то не ноль то либо выполняется то что написано вместо expr2 если это оператор/функция, либо присваивается значение того что содержится в expr2 если в expr2 переменная, число, строка или элемент массива.

а если в expr1 ничего нет или есть но это ноль тогда то что делалось бы с expr2 делается с expr3.

то есть по сути строку
m[c] = m[c] ? m[c] RS $0 : $0
можно переписать как

if (length(m[c]) == 0) #если длина данных в ячейке 0 значит ячейка пустая
m[c]=$0
else
m[c]=( m[c] RS $0 )

то есть задача следующая - надо отсортировать кучу строк по длине строки. при этом если просто присваивать строки в массив вида
имя_массива[длина_строки]=содержимое_строки
то все строки с одной длиной кроме последней такой строки перезапишут друг друга, а надо их все сохранить. и эту проблему решает conditional expression - если в ячейке массива что-то уже записано то к содержимому ячейки приписывается разделитель записей (по умолчанию перевод строки) и содержимое другой строки с такой же длиной. то есть для нас это будет выглядеть так как будто две строки с одной длиной друг за другом идут, а в реальности это одна строка записанная в одну ячейку массива в виде

sprintf "залупа кентавра\nзалупа петровича"

проблемы было две. первая - это уёбищная запись кода на стековерфлоу, из-за которой было тяжело понять какое действие производится первым (может настоящим программистам было бы легко), то есть по нормальному это надо было переписать как
m[c] = ( m[c] ? m[c] RS $0 : $0 )
чтобы было понятно что сначала прогоняется if-then-else в тернарном операторе а потом результат присваивается в ячейку массива.
вторая - это кондовый английский сишных дидов в учебнике, из-за чего я был уверен что "First, expr1 is evaluated" означает что в expr1 обязана быть какая-то операция/функция возвращающая либо 0 либо 1 либо NULL, а первый кусок оператора может и просто в переменную или ячейку массива посмотреть. по иронии судьбы в классическом учебнике по си от того же кернигана есть хорошее объяснение как это работает, а тут логика сишная а объяснение то ли я не нашёл то ли его вообще нет. если учесть что учебник по авк переиздавался сильно меньше то может его и не написали потому что в 80-х все кто знал с какой стороны включать компьютер и так это знали.
1715177041944.png38 Кб, 818x160
51 3395209
>>4689
если вкратце то conditional expression это чрезвычайно изъёбистый способ сишных дидов записать if-then-else, да ещё и описанный английским языком времён молодого брежнева.

то есть при записи

expr1 ? expr2 : expr3

интерпретатор авк смотрит что у нас в expr1. если там переменная или элемент массива то он проверяет есть ли там чего. если там что-то есть и это что-то не ноль то либо выполняется то что написано вместо expr2 если это оператор/функция, либо присваивается значение того что содержится в expr2 если в expr2 переменная, число, строка или элемент массива.

а если в expr1 ничего нет или есть но это ноль тогда то что делалось бы с expr2 делается с expr3.

то есть по сути строку
m[c] = m[c] ? m[c] RS $0 : $0
можно переписать как

if (length(m[c]) == 0) #если длина данных в ячейке 0 значит ячейка пустая
m[c]=$0
else
m[c]=( m[c] RS $0 )

то есть задача следующая - надо отсортировать кучу строк по длине строки. при этом если просто присваивать строки в массив вида
имя_массива[длина_строки]=содержимое_строки
то все строки с одной длиной кроме последней такой строки перезапишут друг друга, а надо их все сохранить. и эту проблему решает conditional expression - если в ячейке массива что-то уже записано то к содержимому ячейки приписывается разделитель записей (по умолчанию перевод строки) и содержимое другой строки с такой же длиной. то есть для нас это будет выглядеть так как будто две строки с одной длиной друг за другом идут, а в реальности это одна строка записанная в одну ячейку массива в виде

sprintf "залупа кентавра\nзалупа петровича"

проблемы было две. первая - это уёбищная запись кода на стековерфлоу, из-за которой было тяжело понять какое действие производится первым (может настоящим программистам было бы легко), то есть по нормальному это надо было переписать как
m[c] = ( m[c] ? m[c] RS $0 : $0 )
чтобы было понятно что сначала прогоняется if-then-else в тернарном операторе а потом результат присваивается в ячейку массива.
вторая - это кондовый английский сишных дидов в учебнике, из-за чего я был уверен что "First, expr1 is evaluated" означает что в expr1 обязана быть какая-то операция/функция возвращающая либо 0 либо 1 либо NULL, а первый кусок оператора может и просто в переменную или ячейку массива посмотреть. по иронии судьбы в классическом учебнике по си от того же кернигана есть хорошее объяснение как это работает, а тут логика сишная а объяснение то ли я не нашёл то ли его вообще нет. если учесть что учебник по авк переиздавался сильно меньше то может его и не написали потому что в 80-х все кто знал с какой стороны включать компьютер и так это знали.
52 3395212
>>4016 (OP)
Надо бы сделать общий тред по всем специализированным линуксовым скриптовым языкам, в первую очередь по башику, но также и по awk, perl, sed и т.д. Кроме питона и руби конечно. Думаю было бы полезнее чем тред по одному awk.
53 3395218
>>5212
честно говоря баш даже для меня слишком простой, я не понимаю зачем по нему отдельный тред. а sed или grep абсолютно ненужен если освоишь awk - awk вообще создавался чтобы делать всё то же самое что и sed и даже больше, только с помощью более читаемого кода. перл наверное норм язык, но у него тяжёлый плохочитаемый синтаксис (по крайней мере в ответах на стековерфлоу перловские ванлайнеры почти всегда нечитаемый набор закорючек который непонятно что делает), в awk хотя бы можно запустить
awk -o- 'иероглифический_пиздец'
и он развернёт ванлайнер в нормальный код. и честно говоря я не очень понимаю чего такого может делать перл чего не смог бы делать awk в связке с башем.
54 3395253
>>5218

>честно говоря баш даже для меня слишком простой


Там свои подводные камни, да и что значит слишком простой? Если забыть про ванлайнеры, то awk еще проще в каком-то смысле. Кроме того идея в том чтобы сделать один общий живой тред, т.к. всем интересно разное и понятно что тред по одному авку долго не протянет. Все эти языки - bash, awk, perl объединяет то что они все связаны с работой в командной строке линукса, поэтому стоило бы линуксоидам иметь свой тредик.
55 3395256
>>5218

>честно говоря баш даже для меня слишком простой


чел не выебываеся так ты не сможешь все-равно.
https://github.com/TheMozg/awk-raycaster
56 3395306
>>5253
ну с awk у меня была проблема вообще понять как скрипт работает. я думал awk работает так же как и любой другой яп - ищет поисковой паттерн и что-то с ним делает или со строкой в которую он входит, вон как питоновский ванлайнер выше. мне тяжело было понять что скрипт буквально проходит построчно весь текст и каждую строку проверяет на вхождение. питоновский скрипт по факту делает то же самое но там синтаксис гораздо привычнее и сам факт построчного прохождения скрыт от программиста. может у меня одного голову от текстоцентричного подхода заклинило, хз.

но вообще ты прав, выёбываться сложностью языка это какие-то колхозные понты. я обеими руками за общий тред окололинуксовых языков, но и этот тред я бы не сносил.
Обновить тред
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски

Скачать тред только с превьюс превью и прикрепленными файлами

Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах.Подробнее