Я пытаюсь вырезать строку с количеством байтов. В чем проблема с этим для l oop? - PullRequest
0 голосов
/ 11 апреля 2020

Заранее извините за вопрос новичка, но я довольно застрял и заинтересован в изучении.

Я пытаюсь отразить строку (в шестнадцатеричном формате), а затем вырезать часть этого с помощью команды cut. Это выглядит так:

for y in "${Offset}"; do
  echo "${entry}" | cut -b 60-$y
done

Где echo $ {Offset} приводит к

75 67 69 129 67 567 69

Я бы хотел, чтобы каждая запись была напечатана, а затем вырезана из 60-го байта до соответствующего число в $ Offset.

Таким образом, первая запись будет обрезана 60-75.

Однако я получаю сообщение об ошибке:

cut: 67: No such file or directory
cut: 69: No such file or directory
cut: 129: No such file or directory
cut: 67: No such file or directory
cut: 567: No such file or directory
cut: 69: No such file or directory

Я попытался добавить / удалить скобки вокруг каждой переменной, но так и не получил правильный результат. Будем благодарны за любую помощь!

ОБНОВЛЕНИЕ: обновлен код с изменением от markp-fuso. Тем не менее, эти коды по-прежнему не работают, как предполагалось. Я хотел бы напечатать каждую запись на основе соответствующего смещения, но это идет не так. Это печатает каждую запись семь раз, где каждый раз основан на семи различных смещениях. Любые идеи о том, как это исправить?

#!/bin/bash

MESSAGES=$( sqlite3 -csv file.db 'SELECT quote(data) FROM messages' | tr -d "X'" )

for entry in ${MESSAGES}; do

  Offset='75 67 69 129 67 567 69'
  for y in $Offset; do
    echo "${entry:59:(y-59)}"
  done
done
echo ${MESSAGES}

В результате получается семь строк с минимальной длиной 80 байт и максимум 600. Мой вывод должен быть:

Строка одна: вырезать сначала смещение

Строка два: вырезать по второму смещению и т. д ...

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Чтобы исключить подпроцесс, который будет вызван из-за | cut ..., мы могли бы взглянуть на сопоставимое решение для расширения параметров ...

Быстрое напоминание о том, как извлечь подстроку из переменной :

${variable:start_position:length}

Помня о том, что первый символ в ${variable} находится в нулевой позиции / 0.

Далее нам нужно преобразовать каждое отдельное смещение (y) в 'length':

length=$((y-60+1))

Обкатка этих изменений в вашем коде (и удаление кавычек из приблизительно ${Offset}) дает нам:

for y in ${Offset}
do
    start=$((60-1))
    length=$((y-60+1))
    echo "${entry:${start}:${length}}"

    #echo "${entry:59:(y-59)}"
done

ПРИМЕЧАНИЕ. Вы также можете заменить start/length/echo с одним закомментированным echo.

Использование меньшего набора данных для демонстрационных целей и использование 3 (вместо 60) в качестве начала нашего извлечения:

# base-10 character position
#                 1         2
#        123456789012345678901234567
$ entry='123456789ABCDEFGHIabcdefghi'

$ echo ${#entry}      # length of entry?
27

$ Offset='5 8 10 13 20'

$ for y in ${Offset}
do
    start=$((3-1))
    length=$((y-3+1))
    echo "${entry:${start}:${length}}"
done

345                  # 3-5
345678               # 3-8
3456789A             # 3-10
3456789ABCD          # 3-13
3456789ABCDEFGHIab   # 3-20

И объединение start/length/echo в один echo:

$ for y in ${Offset}
do
    echo "${entry:2:(y-2)}"
done

345                  # 3-5
345678               # 3-8
3456789A             # 3-10
3456789ABCD          # 3-13
3456789ABCDEFGHIab   # 3-20
0 голосов
/ 11 апреля 2020

Чтобы for перебирал каждое разделенное пробелами "слово" в $Offset, вам нужно избавиться от кавычек, которые делают его читаемым как одна переменная.

for y in ${Offset}; do
  echo "${entry}" | cut -b 60-$y
done
...