Как анализировать определенные строки из нескольких файлов с помощью сценария оболочки

В старые времена телетайпы были пишущими машинками, которые переводили то, что было напечатано локально на механической пишущей машинке, в коды EBCDIC или ASCII, а затем передавали по кабелю на удаленный компьютер. Отсюда и приставка «теле», что означает «на расстоянии». Иногда использовалось слово «терминал», потому что телетайп был конечным концом провода, где вводились данные и передавались на компьютер или приемную станцию. Каждое устройство «tty» подключалось через последовательный порт, потому что медный провод был дорогим, и поэтому устройства с «параллельным» портом в основном использовались для интерфейсов на короткие расстояния -, например, для локального принтера. Это было до того, как беспроводные сети стали широко использоваться. В прежние времена многопользовательской компьютерной среды -можно было иметь несколько «терминальных устройств», т. е. устройств «tty», подключенных к одному и тому же центральному компьютеру. Это исходная аппаратная среда, в которой разрабатывалась Unix. Это аппаратное наследие все еще с нами в наименовании программных компонентов в операционной системе Linux.

Сегодня в Linux tty — это устаревшее имя, используемое для обозначения пользовательского интерфейса для текстового -ввода и вывода, также известного как «терминал». В системах Linux может быть несколько «консолей» tty-устройств, потенциально поддерживающих десятки или более последовательных портов. В настоящее время используется tty0, но Linux позволяет вам переключиться на другой сеанс, заменив другой tty, например, tty1. Linux (, например, Ubuntu )по умолчанию поддерживает до 6 tty, но это число можно настроить.

С практической точки зрения tty представляет собой последовательный канал связи, который сеанс Linux использует для связи с пользователем.

Это работает так: существует процесс анализа, привязанный к сеансу tty, который анализирует ввод пользователя и передает допустимые команды компьютеру для выполнения.

1
22.03.2021, 14:08
1 ответ

sedвариант:

sed -n -E -e '/^Backtrace:/ {s/Backtrace://; s/:0x3ff[^ ]* */ /g; p}' input.txt

Это игнорирует все строки, которые не начинаются с "Backtrace :", и использует два правила поиска и замены для изменения совпадающих строк перед их печатью.

Операция s/:0x3ff[^ ]* */ /gсоответствует любому тексту, начинающемуся с :0x3ff, за которым следует ноль -или еще -не -пробелов ([^ ]*), за которыми следует ноль -или еще -пробелов( *)и заменяет все найденные совпадения одним пробелом. Это глобальный поиск и замена (/g), поэтому он повлияет на все совпадения, найденные в строке, а не только на первое совпадение.

Он не пытается ограничить свое действие только строками между «Медитация Гуру» и «Перезагрузка». Этого должно быть достаточно, если во входных данных нет других строк, начинающихся с «Backtrace :», или если вы загружаете только один входной файл за раз.

Если 0x3ffне является постоянным при нескольких запусках, его можно изменить на регулярное выражение, которое соответствует двоеточию, за которым следует 0x, за которым следует 1 или более шестнадцатеричных цифр. например.

s/:0x[0-9a-f]+//gi

Это изменение также можно использовать с приведенными ниже версиями awk и perl, если это необходимо.

awkверсия:

awk -v SKIP=1 '/^Guru Meditation Error/ { SKIP=0 };
               /^Rebooting\.\.\./ { SKIP=1} ;
               SKIP==1 || ! /^Backtrace:/ { next };
               {
                   sub("^Backtrace:","");
                   gsub(":0x3ff[^ ]* *"," ");
                   print
               }
              ' input.txt

Это пропускает все вводимые данные, которые не находятся между строками «Guru Meditation» и «Rebooting», а также все вводимые данные, которые не начинаются с «Backtrace :».Затем он изменяет непропущенные строки -с помощью двух операций поиска и замены(sub()иgsub())перед печатью измененной строки.

Perl-версия:

perl -lne 'BEGIN {$SKIP=1};
           $SKIP=0 if (m/^Guru Meditation Error/);
           $SKIP=1 if (m/^Rebooting\.\.\./);
           next if ($SKIP || ! m/^Backtrace:/);
           s/Backtrace://;
           s/:0x3ff\H*\h*/ /g;
           print' input.txt

Это работает так же, как версия awk, но код выглядит как нечто среднее между версиями awk и sed (perl поддерживает синтаксис как awk -, так и sed -... и многое другое. больше ).

Конечная s//gоперация была изменена, чтобы использовать perl\H(не -символ горизонтального пробела )и\h(символ горизонтального пробела )вместо просто пробелов (т.е. табуляции и пробелы и многое другое -см. man perlrecharclassи найдите раздел «Пробелы» для подробностей)

Вывод для всех трех версий идентичен:

0x4000814d 0x40082259 0x400833b9 0x400833e2 0x40081e6a 0x4008a2e5 0x4008438d 0x400830ed 0x40083271 0x400de4b1 0x400dd525 0x400dd7c5 0x400de175 0x400dccf2 0x400dcedf 0x400dcf47 0x400dbebf 0x400dbed2 0x400d757a 0x400d770a 0x400d3a66 

Все три версии способны принимать ввод из стандартного ввода или из одного или нескольких имен файлов (с )в командной строке. В приведенных выше примерах используется текстовый файл input.txt(, который я копирую -и вставляю ваш образец ввода в ).

Все они выводятся на стандартный вывод, поэтому их можно использовать для подстановки команд. например.

addr2line xtensa-esp32- -pfiaC -e project.elf $(sed -n -E -e '/^Backtrace:/ {s/Backtrace://; s/:0x3ff[^ ]* */ /g; p}' input.txt)
0
28.04.2021, 22:57

Теги

Похожие вопросы