Официальная возможность получить лицензионный софт бесплатно.
Giveaway of the Day
Это не реклама!

Щелкните для получения прогноза по Биробиджану


Показаны сообщения с ярлыком цикл. Показать все сообщения
Показаны сообщения с ярлыком цикл. Показать все сообщения

среда, 29 мая 2019 г.

MySQL: цикл со счетчиком, который используется для получения остальных полей

Задал вопрос на StackOverflow (на английском). И, видать, так тщательно его описал, что сам понял, как на него ответить.

Абстракт: нужно организовать цикл со счетчиком, и счетчик цикла использовать для выборки чего-либо из базы данных MySQL без использования временных таблиц и прочей ереси.

Теперь опишу здесь ситуацию по-русски:

Итак, как я уже писал, в моей конторе используются кодированные имена компьютеров. Кодировка описывается простым регэкспом:

cnt30[0-9]{3}[1-9a-z]{1}

где часть  [0-9]{3} по сути - номер рабочего места, а хвост [1-9a-z]{1} (в предыдущем посте я неправильно указал, что хвост начинается с нуля) - "квалификатор", указывающий на номер компьютера для этого рабочего места. Например, cnt300022 может быть десктопом на рабочем месте №002, а cnt30002a - ноутбуком, закрепленным за этим местом.

вторник, 2 мая 2017 г.

MS DOS: Обращение к счетчику цикла изнутри самого цикла

Как ни крути, а cmd.exe и command.com - это останки MS DOS, поэтому я так и озаглавил эту запись.

Итак, server 2008, cmd.exe, батник, цикл... Что я хочу сделать? Я хочу вывести числа от 1 до 20, причем числа меньше 10 должны выводиться с ведущими нулями. Способов для этого много, но все они упираются в присвоение какой-то переменной текущего значения счетчика цикла.
Чтобы не мудрить с проверками, я решил использовать наиболее универсальный способ: прибавляю к числу 100 и из полученного значения беру 2 правых символа. Можно прибавлять что угодно, главное, чтобы справа было нужное число нулей, чтобы не исказить само значение.

for /L %%a in (1,1,20) do (
  set /A b=100+%%a
  set b=%b:~-2%
  echo a=[%%a] b=[%b%]
)

По идее у меня должно напечататься 20 строк вида:

a=[x] b=[zy]

где x - значение переменной счетчика цикла, y=x, а z - ведущий ноль, если он есть.

Однако, вместо этого печатаются строчки вида:

a=[x] b=[]

Я перепробовал все варианты, какие только смог придумать. Увы, все команды работают с %%a нормально, кроме команды присвоения. Вариант с setlocal EnableDelayedExpansion тоже не помог. Пришлось выкручиваться. Частично решение, саму идею, нашел здесь.


for /L %%a in (1,1,20) do (
  call :MySub %%a
  echo a=[%%a] b=[%b%]

)

exit /b 0

:MySub
  set /A b=100+%~1
  set b=%b:~-2%

exit /b 0


После этого всё заработало.

Вывод: если надо что-то сделать со значением счетчика цикла, сложнее чем вывести его значение на экран, то для этого лучше передать его как параметр в подпрограмму.

понедельник, 12 октября 2015 г.

Немножко о циклах и nslookup

Просто для памяти: массовый nslookup последовательных имен хостов

for a in `seq 56 65`; do nslookup cont30prn0$a|grep "Name:" -A 1; done

С командой seq я уже разбирался ранее, объясню про grep в данной ситуации: nslookup выдает несколько строк информации по каждому хосту, но мне нужны только две - название и адрес искомого хоста, и совершенно не интересны строки с информацией о DNS-сервере и т.п. Поэтому ищу строчку со словом "Name:" и вывожу на экран её и еще одну строку после (-A 1)

Name:    cont30prn056.my.domain
Address: 172.21.123.20
Name:    cont30prn057.my.domain
Address: 172.21.126.157
Name:    cont30prn058.my.domain
Address: 172.21.123.13
Name:    cont30prn059.my.domain
Address: 172.21.123.37
Name:    cont30prn060.my.domain
Address: 172.21.124.203
Name:    cont30prn061.my.domain
Address: 172.21.124.204
Name:    cont30prn062.my.domain
Address: 172.21.123.62
Name:    cont30prn063.my.domain
Address: 172.21.123.63
Name:    cont30prn064.my.domain
Address: 172.21.123.64
Name:    cont30prn065.my.domain
Address: 172.21.123.65

С обратным nslookup несколько проще - вся нужная информация выводится в одной строке, но вот со списком непоследовательных адресов морока.

for a in 123.20 126.157 123.13 123.37 124.203 124.204 123.62 123.63 123.64 123.65; do nslookup 172.21.$a|grep in-addr; done

20.123.21.172.in-addr.arpa    name = cont30prn056.my.domain.
157.126.21.172.in-addr.arpa    name = cont30prn057.my.domain.
13.123.21.172.in-addr.arpa    name = cont30prn058.my.domain.
37.123.21.172.in-addr.arpa    name = cont30prn059.my.domain.
203.124.21.172.in-addr.arpa    name = cont30prn060.my.domain.
204.124.21.172.in-addr.arpa    name = cont30prn061.my.domain.
62.123.21.172.in-addr.arpa    name = cont30prn062.my.domain.
63.123.21.172.in-addr.arpa    name = cont30prn063.my.domain.
64.123.21.172.in-addr.arpa    name = cont30prn064.my.domain.
65.123.21.172.in-addr.arpa    name = cont30prn065.my.domain.

четверг, 28 августа 2014 г.

Формирование списка чисел заданной ширины: seq

Понадобилось мне создать энное количество каталогов вида "каталогХХХ", где ХХХ - последовательные номера в диапазоне от 0 до 999, но не обязательно весь диапазон, например, от 6 до 155. При этом ХХХ - всегда три знака, стало быть

Конструкция for и "развёртывание фигурных скобок" (brace expansion - ABSG, ch.36, p.528)?

#start - начальный номер, finish - конечный
for i in {$start..$finish}; do ... ; done


Не пойдет! Потому что "развертывание" не поддерживает использование переменных, и $i примет текстовое значение "{начальный_номер..конечный_номер}" вместо ожидаемого набора чисел в нужном интервале.

Может вернуться ко временам DOS и сделать три вложенных цикла? Можно, и оно даже будет работать:

for i in {0..9}
  for j in {0..9}
    for k in {0..9}
      if [ $i$j$k -lt $start ] || [ $i$j$k -gt $finish ] then break
      mkdir каталог$i$j$k
...

Но зачем крутить лишние циклы и делать кучу лишних проверок на попадание в диапазон? В общем, команда seq рулит! Потребовалось некоторое время, чтобы вспомнить формат pfintf-a, но оно того стоило.

Сначала попробовал с ключом -w - выровнять ширину: если числа в последовательности имеют разную ширину, например "1" и "123", то меньшие будут дополняться ведущими нулями - для диапазона 1..111 "1" превратится в "001", "10" - в "010". Чудесно! Чудесно? Мне-то надо, чтобы было всегда три знака, независимо от конечного значения, а здесь три знака будут только если конечное значение трехзначное, увы. (с тоской вспоминаю Clarion, где такие вещи решались на "раз-два")

Что ж, раз ключ -w не подходит, попробуем поиграться с -f - формат вывода. А вот это - то, что доктор прописал:

for i in $( seq -f %03g 0 $max_dir_number )
do
    dir_name="каталог$i"
    mkdir $dir_name
    chown $owner_name:$owner_group $dir_name
    chmod 777 $dir_name
done


формат %03g как раз делает то, что я хочу: дополняет нулями слева (0), до трех знаков (3). Честно скажу, не помню, для чего суффикс "g", я тупо взял его из подобного примера. Но работает именно так, как надо.