Ребус на Bash (sed, awk и т.д.)

Тема в разделе "Программирование", создана пользователем электрик, 14.12.17.

  1. электрик

    электрик Активный участник

    3.812
    201
    Дана текстовая строка. Можно брать как с переносом, как в первом примере, так и потоком. Не важно.
    Код:
    00
    00
    00
    00
    00
    01
    1E
    14
    00
    00
    01
    00
    00
    01
    11
    10
    00
    00
    02
    00
    00
    01
    1A
    11
    00
    03
    00
    00
    0B
    0E
    0F
    0F
    00
    08
    01
    11
    00
    01
    00
    00
    0B
    0E
    0F
    0F
    01
    10
    18
    00
    03
    01
    00
    либо
    Код:
    0000000000011E1400000100000111100000020000011A11000300000B0E0F0F0008011100010000B0E0F0F011018000301000B
    Так вот. Нужно его в скрипте разбить на строки по следующему условию.
    Рассмотрим небольшой участок:
    Код:
    00
    01
    1A
    11
    00
    03
    00
    Видите, в первой позиции у нас появляется единица в старшем разряде?
    Нужно расхреначить поток по условию, что после смены единицы на ноль в старшем разряде - новая строка.
    Т.е. должно получиться:
    Код:
    0000000000011E14
    0000010000011110
    0000020000011A11
    000300000B0E0F0F00080111
    00010000B0E0F0F011018
    000301000B...
    Пока я пол дня писал преобразование 18 мегабайт хлама вот в эти 500кб удобоваримых данных у меня мозг уже пополам треснул. Подскажите, пожалуйста, как проще сделать. Даже не обязательно башем. Это одноразовая операция. 3 разных потока по одному разу преобразовать и все.
     
  2. gerodoth

    gerodoth Активный участник

    10.559
    1.290
    для каждого символа через один начиная с первого
    если символ единица и если через один не ноль то
    пока текущий символ не ноль перейти на 2 вправо.
    обрезать с начала строки по текущее место, добавить вырезанное к массиву слов
    конец если
    если оставшаяся строка короче 4 символов добавить ее к массиву, выход
    с оставшейся строкой пока повторить итерацию
     
  3. электрик

    электрик Активный участник

    3.812
    201
    Туго.
    Давай упростим задачу.
    Переделал в
    Код:
    01x19x17x1Bx17x19x17x1Bx17x00x09x04x00x0D
    Т.е. нам сейчас заменить шаблон
    Код:
    1*x0
    на
    1*x(CR)0 или 1*xz0
    Под звездочкой любые символы [0-F]
    А х, z и новые строки я потом расхреначу

    p.s. Мне бы на sed готовое выражение :)
     
    Последнее редактирование: 14.12.17
  4. gerodoth

    gerodoth Активный участник

    10.559
    1.290
    sed я не осилил даже когда он мне нужен был, теперь и я старый и он не так нужен, но по идее регэкспами прям чу-чуть пошерудить осталось
     
  5. Lord Beaver

    Lord Beaver Активный участник

    1.935
    314
    Так?
    Код:
    # echo "01x19x17x1Bx17x19x17x1Bx17x00x09x04x00x0D" | sed -r 's/1(.)x0/1\1x\n0/g' | sed 's/x//g'
    0119171B1719171B17
    000904000D
    Без иксов:
    Код:
    # echo "0000000000011E1400000100000111100000020000011A11000300000B0E0F0F00080111000100000B0E0F0F01101800030100" | sed -r 's/(..)/\1 /g' | sed -r 's/1(.) 0/1\1\n0/g'
    00 00 00 00 00 01 1E 14
    00 00 01 00 00 01 11 10
    00 00 02 00 00 01 1A 11
    00 03 00 00 0B 0E 0F 0F 00 08 01 11
    00 01 00 00 0B 0E 0F 0F 01 10 18
    00 03 01 00
    # echo "0000000000011E1400000100000111100000020000011A11000300000B0E0F0F00080111000100000B0E0F0F01101800030100" | sed -r 's/(..)/\1 /g' | sed -r 's/1(.) 0/1\1\n0/g' | sed 's/ //g'
    0000000000011E14
    0000010000011110
    0000020000011A11
    000300000B0E0F0F00080111
    000100000B0E0F0F011018
    00030100
     
    Последнее редактирование: 14.12.17
    Slv и электрик нравится это.
  6. электрик

    электрик Активный участник

    3.812
    201
    @Lord Beaver, спасибо! Получилось! Только пришлось -r на -E заменить и вместо перевода строки просто символ n писался, но это легко заплаткой из tr решилось.