Уголок для новичков

Программирование на sh, быть может немного про альтернативные языки
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Jungo
рядовой
Сообщения: 13
Зарегистрирован: 2008-08-24 18:01:24

Уголок для новичков

Непрочитанное сообщение Jungo » 2015-11-14 22:48:04

Добрый вечер уважаемые администраторы операционных систем с открытым исходным кодом :good: и все остальные
почитывал на досуге статейку про awk и sed - http://www.lissyara.su/doc/programming/awk/
и не дает мне покоя вот этот пример:

Код: Выделить всё

awk ' BEGIN {FS = "."; a=0}
length ($1) > 8 {print (length ($1), $0);
a++ 
}
END {print ("Найдено строк: " a) }' ./f-awk
где-то в зарождающихся складках моего атрофированного мозга я понимаю что мы устанавливаем на вводе разделитель "." - точку
присваиваем переменной a значение 0 - ноль
далее если длина первого поля больше 8 символов, то печатаем длину первого поля и всю строку
далее прибавляем к переменной a единицу и повторяем измерение длины первого поля

f-awk содержит в себе

Код: Выделить всё

Иванов И.И. 1980 50
Петров А.В. 1979 40
Сидоров С.К. 1979 40
Хведоров И.Х. 1970 60
но почему я получаю вот такое в консоли, простите дебиана

Код: Выделить всё

15 Иванов И.И. 1980 50
15 Петров А.В. 1979 40
17 Сидоров С.К. 1979 40
19 Хведоров И.Х. 1970 60
а если поменять например вот на такое

Код: Выделить всё

9 ivanov И.И. 1980 50
то ситуация нормализуется
такое ощущение, что русские буквы занимают места больше, чем должны

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
trubb
лейтенант
Сообщения: 865
Зарегистрирован: 2005-03-16 17:42:26
Откуда: сами мы не местные, приехали на лечение

Уголок для новичков

Непрочитанное сообщение trubb » 2015-11-15 21:18:53

я хз но когда работаешь с юникодом на русские буквы реально больше байт уходит )))
когда вышла RAD с поддержкой юникода и стало можно переменные называть по русски - требование к длине имени переменной в юникоде - ровно в два раза меньше чем на латинице - вот так то
иГрАюВсТрАйКбОл!

lazhu
сержант
Сообщения: 254
Зарегистрирован: 2013-08-10 14:28:38
Контактная информация:

Уголок для новичков

Непрочитанное сообщение lazhu » 2015-11-16 9:49:46

Каждый кириллический символ UTF-8 занимает 2 байта: http://www.utf8-chartable.de/unicode-utf8-table.pl

Jungo
рядовой
Сообщения: 13
Зарегистрирован: 2008-08-24 18:01:24

Уголок для новичков

Непрочитанное сообщение Jungo » 2015-11-16 14:12:40

lazhu, спасибо!
если у кого то есть простые вопросы по

Код: Выделить всё

awk
sed
cat
grep
egrep
fgrep
lex
sort
uniq
cut
print
wc
пишите, пока мне это самому интересно, в целях самообразования буду стараться помочь

FiL
ст. лейтенант
Сообщения: 1375
Зарегистрирован: 2010-02-05 0:21:40

Уголок для новичков

Непрочитанное сообщение FiL » 2015-11-16 21:06:31

а на чем тестируешь?
А то GNU awk вполне себе unicode-aware. A вот BSD - хрен.
Потому надо пользовать gawk и не крутить себе...

Jungo
рядовой
Сообщения: 13
Зарегистрирован: 2008-08-24 18:01:24

Уголок для новичков

Непрочитанное сообщение Jungo » 2015-11-16 22:14:21

bash
awk
LANG=en_US.UTF-8
текст набивал через nano

если установить gawk то ситуация нормализуется

Код: Выделить всё

awk ' BEGIN {FS = "."; a=0}
length ($1) > 8 {print (length ($1), $0);
a++
}
END {print ("Найдено строк: " a) }' ./awk.log
9 Сидоров С.К. 1979 40
10 Хведоров И.Х. 1970 60
Найдено строк: 2
чего не скажешь без установленного gawk

Код: Выделить всё

awk ' BEGIN {FS = "."; a=0}
length ($1) > 8 {print (length ($1), $0);
a++
}
END {print ("Найдено строк: " a) }' ./awk.log
15 Иванов И.И. 1980 50
15 Петров А.В. 1979 40
17 Сидоров С.К. 1979 40
19 Хведоров И.Х. 1970 60
Найдено строк: 4



Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35465
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Уголок для новичков

Непрочитанное сообщение Alex Keda » 2015-12-01 8:26:27

Откуда на дебилиане не-гнуАВК ? ;)
Убей их всех! Бог потом рассортирует...

Аватара пользователя
Neus
майор
Сообщения: 2006
Зарегистрирован: 2008-09-08 21:59:56

Уголок для новичков

Непрочитанное сообщение Neus » 2015-12-01 8:59:26

Пакет gawk
jessie (stable) (interpreters): язык шаблонного сканирования и обработки GNU awk
1:4.1.1+dfsg-1: amd64 arm64 armel armhf i386 mips mipsel powerpc ppc64el s390x

Пакет mawk
jessie (stable) (interpreters): Язык обработки текстов и поиска по шаблону.
1.3.3-17+b2: arm64
1.3.3-17+b1: ppc64el
1.3.3-17: amd64 armel armhf i386 mips mipsel powerpc s390x

Пакет original-awk
jessie (stable) (interpreters): The original awk described in "The AWK Programming Language"
2012-12-20-2: amd64 arm64 armel armhf i386 mips mipsel powerpc ppc64el s390x

mozay
проходил мимо
Сообщения: 4
Зарегистрирован: 2016-08-17 15:51:41

Уголок для новичков

Непрочитанное сообщение mozay » 2016-08-19 21:43:20

Подниму тему.
Вот решил такой файл помучать:

Код: Выделить всё

'27967','1','+73439758384','+73439758384','+73439758384','+73439758384','+73439758384','3600',NULL
'27967','2','+73439758385','+73439758385','+73439758385','+73439758385','+73439758385','3600',NULL
'27967','3','+73439758386','+73439758386','+73439758386','+73439758386','+73439758386','3600',NULL
хочется получить возможность генерить файл с другими номерами, например большими на известную величину, и это даже кое как почти получилось:

Код: Выделить всё

'27967 1 '+73439758448' '+73439758448' '+73439758448' '+73439758448@xxx.yy.ru' 73439758448 3600',NULL
'27967 2 '+73439758449' '+73439758449' '+73439758449' '+73439758449@xxx.yy.ru' 73439758449 3600',NULL
'27967 3 '+73439758450' '+73439758450' '+73439758450' '+73439758450@xxx.yy.ru' 73439758450 3600',NULL
c помощь вот такой конструкции:

Код: Выделить всё

#!/bin/awk -f
BEGIN { 
        FS="','"  # заодно с разделитем  знаки ' '
        num = 64 
} 
{($3=$3+num) #добавляется число портов на плате к числу в 3м поле
($3="'+" $3 "'") #возвращаем число к виду строки со знаком +
 ($4=$4+num) #добавляется число портов на плате к числу в 4м поле
 ($4="'+" $4 "'")
 ($5=$5+num)
 ($5="'+" $5 "'")
 ($6=$6+num) 
 ($6="'+" $6 "@xxx.yy.ru'")
 ($7=$7+num)
     ; print} 
Но как то совсем не кошерно получилось. Надо на выходе точно такой же формат полей с номерами в одинарных кавычках, разделитель полей - "," , одинарные кавычки не дают делать арифметические операции с содержимым полей. И что-нибудь да теряется нужное. Решил удалить лишнее для начала, а потом, после математики, вставить обратно.

Код: Выделить всё

{for( i = 1; i < NF; i++ )
	gsub(/'/, " ", $i)}
Но обратное действие не получается провести.
Вобщем посоветуйте как красиво сделать. Может совсем с другой стороны зайти как то.

FiL
ст. лейтенант
Сообщения: 1375
Зарегистрирован: 2010-02-05 0:21:40

Уголок для новичков

Непрочитанное сообщение FiL » 2016-08-19 22:51:07

ну, если по-простому, то

Код: Выделить всё

#!/bin/awk -f
BEGIN {
        FS="','"  # заодно с разделитем  знаки ' '
        OFS="','"
        num = 64
}
{
($3=$3+num) #добавляется число портов на плате к числу в 3м поле
($3="+" $3) #возвращаем число к виду строки со знаком +
 ($4=$4+num) #добавляется число портов на плате к числу в 4м поле
 ($4="+" $4)
 ($5=$5+num)
 ($5="+" $5)
 ($6=$6+num)
 ($6="+" $6 "@xxx.yy.ru")
 ($7=$7+num)
 print
}

mozay
проходил мимо
Сообщения: 4
Зарегистрирован: 2016-08-17 15:51:41

Уголок для новичков

Непрочитанное сообщение mozay » 2016-08-20 0:26:32

Да, работает по вашему! а меня смутило, что у последнего поля нет ' и как бэ будет не понятно что в результате обработается.
А вообще примерно к этому же пришёл:

Код: Выделить всё

#!/bin/awk -f

BEGIN { 
        FS=","  					# входной разделитель полей
        OFS = "," 					# выходной разделитель полей
        num = 64  					# число портов на плате, будет добавляться к предыдущим значениям
} 
{	
{for( i = 1; i < NF; i++ )		# этот цикл заменяет все одинарные кавычки в полях на пустоту, не доходя последнего поля
 gsub(/'/,"",$i)				# тем самым, можем делать математику с полями, "+" не помешает.
}			
{for( i = 1; i < NF; i++ )		# этот цикл все поля содержащие номера абонентов с цифрой +7
 if ($i~"+7") ($i = $i + num)	# увеличит на нужное число num, после этой операции знак "+" пропадает
}
 ($6=$6 "@zzz.rt.ru") 			# в 6-е поле добавляем суффикс (по ТР) (объединение эл-в строки производится через пробел)
 sub(/734397/, "XXX", $7) 		# в 7м поле заменяется первое попадание значения из "//" на XXX (по ТР) 
{for( i = 1; i < NF; i++ )		# возвращаем "+" на места, 
 if ($i~/^7343/) ($i="+" $i)}	# все поля начинающиеся на 7343.
{for( i = 1; i < NF; i++ )		# возвращаем '' на места, 
 ($i="'" $i "'")}				# все поля кроме последнего окружаются ими.
  ; print > 33.txt } 			#вывод в файл
подробные коментарии для себя пишу, чтобы самому вспомнить что и куда.
Так вот, есть ещё странность для меня: если сохраняю вывод в файл как сейчас 33.txt то всё удачно пишется. Если же стоит назвать файл как то account.txt то беда:

Код: Выделить всё

awk -f mytest4.awk sip_account.dat 
awk: mytest4.awk:23:      ; print > account.txt } 				#вывод в файл 
awk: mytest4.awk:23:                       ^ syntax error

FiL
ст. лейтенант
Сообщения: 1375
Зарегистрирован: 2010-02-05 0:21:40

Уголок для новичков

Непрочитанное сообщение FiL » 2016-08-22 19:05:51

1) последнее поле будет 3600',NULL (вот такое вот странноватое поле). Но так, как с ним ничего делать не надо, то и хрен с ним.
2) лучше все-таки вывод в файл делать не внутри awk'a, а снаружи. Пусть awk печатает на экран, а ты уже потом выводи вывод в файл -

Код: Выделить всё

awk -f mytest4.awk sip_account.dat  > account.txt