Как удалить конкретные номера из txt-файла с помощью SED или AWK?

Первоначальное исследование

На первый взгляд может показаться, что ответ будет «нет», спецификация для ELF допускает только следующие разделы.

C32/kernel/bin/.process.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000333  00000000  00000000  00000040  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000050  00000000  00000000  00000380  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  000003d0  2**2
                  ALLOC
  3 .note         00000014  00000000  00000000  000003d0  2**0
                  CONTENTS, READONLY
  4 .stab         000020e8  00000000  00000000  000003e4  2**2
                  CONTENTS, RELOC, READONLY, DEBUGGING
  5 .stabstr      00008f17  00000000  00000000  000024cc  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .rodata       000001e4  00000000  00000000  0000b400  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .comment      00000023  00000000  00000000  0000b5e4  2**0
                  CONTENTS, READONLY

Источник: http://wiki.osdev.org/ELF

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

.fini

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

.init

В этом разделе содержатся исполняемые инструкции, которые вносят вклад в код инициализации процесса. То есть, когда программа начинает работать, система выполняет код в этом разделе до точки входа в основную программу (называемую main в программах на языке C).

Разделы .init и .fini имеют особое назначение. Если функция помещена в раздел .init , система выполнит ее перед основной функцией . Также функции, помещенные в раздел .fini , будут выполняться системой после возврата из основной функции. Эта функция используется компиляторами для реализации глобальных конструкторов и деструкторов в C ++.

Источник: http: //l4u-00.jinr.ru / usoft / WWW / www_debian.org / Documentation / elf / node3.html

Но да, у вас могут быть любые разделы

Но спасибо @AProgrammer за то, что он указал мне на настоящий ] Спецификация ELF v1.2 , на странице 1-16 есть параграф, в котором говорится следующее:

Имена разделов с префиксом точки (.) Зарезервированы для системы, хотя приложения могут использовать эти разделы, если они существуют. значения удовлетворительны. Приложения могут использовать имена без префикса, чтобы избежать конфликтов с разделами системы. Формат объектного файла позволяет определять разделы, которых нет в списке выше. В объектном файле может быть несколько разделов с одинаковым именем.

Таким образом, может показаться, что программа полностью решает, какие разделы она хочет использовать.

4
17.02.2019, 20:49
2 ответа

С AWK все довольно просто, т. к. обычно AWK ничего не делает, поэтому нам просто нужно сообщить ему, когда что-то делать, т.е. напечатать идентификатор в начале строки, если он там есть

/^[0-9]+-[0-9]+\.[0-9]+\.501\.[0-9]+/{
    print $1
}

С sed немного по-другому, b/c по умолчанию sed напечатает все. (По крайней мере, у меня эти инструменты работают именно так. )Во-первых, нам нужно вызвать sedкак sed -n, чтобы изменить его поведение по умолчанию и ничего не делать. Тогда мы можем

s/^\([0-9]\+-[0-9]\+\.[0-9]\+\.501\.[0-9]\+\).*$/\1/p

Нам нужно pв конце, чтобы сообщить sed p rint результат, если у нас есть соответствующий шаблон. Ваше конкретное выражение sed — это NOOP , потому что оно заменяет каждое совпадение самим собой и печатает все остальное как есть.

7
27.01.2020, 20:46

Это работает, но вы ничего не меняете, вернее, меняете на то, что было. Но с очень небольшой модификацией этого кода вы можете получить то, что хотите:

sed -n 's/\([0-9]*\-[0-9]*\.[0-9]*\.501\.[0-9]*\).*/\1/p'

Обратите внимание на три вещи:

  • -nпереключатель, по умолчанию означает ничего не печатать
  • .*в конце группы, выбранной с помощью(...)
  • pкак последняя команда означает печать этой строки

Результат:

010010-26.2010.501.0026
0011-15.2016.501.0012
0011-125.2013.501.0012

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

sed -E -n 's/([0-9]*-[0-9]*\.[0-9]*\.501\.[0-9]*).*/\1/p'

Оба способа работают на указанной веб-странице.

7
27.01.2020, 20:46

Теги

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