Как получить все строки между первыми и последними случаями шаблонов?

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

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

Когда люди начнут получать пакеты, подписанные с новым ключом, они получат сообщение об ошибке, говоря им, что пакеты не подписаны. Это, надо надеяться, запросит их в запрос, что происходит и пытается получить новый ключ.

О компромиссе также объявят в списках рассылки безопасности и в различных каналах отраслевых новостей. Таким образом, если Вы будете следовать за ними, то Вы получите уведомление. Конечно, необходимо опасаться их также: взломщик мог бы поставить под угрозу сервер списка или учетную запись разработчика и отправить поддельное ключевое предупреждение компромисса с новым открытым ключом, который является на самом деле для его собственного закрытого ключа.

Нет никакого чудодейственного средства для распределения нового ключа. Вам нужен доверяемый канал, чтобы распределить ключ во-первых или более точно установить доверие новому ключу. Это точно столь же трудно как устанавливающий доверие старому ключу. (Другими словами, большинство людей получит его от веб-сайта HTTP или от неподписанного образа CD.) Можно получить новый ключ от веб-сайта HTTPS, если Вы полагаете, что веб-сайт (и CA, который сделал сертификат сайта и браузер, который Вы используете и его доверяемая основа!) не был поставлен под угрозу. Или если Вы знаете и доверяете кому-то, у кого есть ключ, можно попросить у них его.


Обратите внимание, что выше, я использую “пакет” в свободном смысле, принимая простую модель, где пакеты непосредственно подписываются с ключом подписи распределения. На самом деле, в некоторых дистрибутивах (например, все те, которые используют APT), то, что подписывается, является файлами, содержащими список криптографических контрольных сумм пакетов, и существует двухэтапный процесс, посредством чего установщик проверяет, что пакет имеет ожидаемую контрольную сумму, и что список имеет контрольную сигнатуру. Принцип является тем же: взломщик, который поставил под угрозу ключ, введет и злонамеренные пакеты и перечислит файлы с контрольными суммами для злонамеренных пакетов, подписанных с поставленным под угрозу ключом. Разрешение требует восстановления и файлы списка и пакеты.

8
13.09.2012, 02:06
7 ответов
sed -n '/foo/{:a;N;/^\n/s/^\n//;/bar/{p;s/.*//;};ba};'

sed сопоставление с образцом /first/,/second/ строки чтений один за другим. Когда некоторая строка соответствует к /first/ это помнит это и ожидает к первому соответствию для /second/ шаблон. В то же время это применяет все операции, указанные для того шаблона. После того, как тот процесс запускается снова и снова в конец файла.

Это не то, что нам нужно. Мы должны посмотреть до последнего соответствия /second/ шаблон. Поэтому мы создаем конструкцию, которая просто ищет первую запись /foo/. При нахождении цикла a запускается. Мы добавляем новую строку к буферу соответствия с N и проверьте, соответствует ли это к шаблону /bar/. Если это делает, мы просто печатаем его и очищаем буфер соответствия и переход janyway к начинанию цикла с ba.

Также мы должны удалить символ новой строки после буферной уборки с /^\n/s/^\n//. Я уверен, что существует намного лучшее решение, к сожалению, оно не прибыло по моему мнению.

Надежда все ясно.

6
27.01.2020, 20:10
  • 1
    , Это работает! Это было бы очень прикольно, если Вы могли бы обойти нас через конструкцию такой команды. Я чувствовал бы себя, что немым просто копирую/вставляю его с некоторого веб-сайта ;) –  rahmu 12.09.2012, 18:41
  • 2
    Извините я не отправил объяснение с ответом. Теперь это находится в сообщении. –  rush 12.09.2012, 18:58
  • 3
    В некоторых sed версии, например, BSD sed (который является тем, что найдено на Mac), отмечает потребность, которая будет сопровождаться новой строкой или концом строки, таким образом, следующая тонкая настройка необходима: sed -n -e '/foo/{:a' -e 'N;/^\n/s/^\n//;/bar/{p;s/.*//;};ba' -e '};' Это также работает над GNU sed, таким образом, я думаю эта модификация (несколько -e окончание args аргумента после каждого имени ответвления), хорошая портативная привычка войти при использовании ответвлений в sed. –  Wildcard 26.11.2015, 15:07

Вот является GNU с двумя передачами sed решением, которое не требует большой памяти:

< infile                                     \
| sed -n '/foo/ { =; :a; z; N; /bar/=; ba }' \
| sed -n '1p; $p'                            \
| tr '\n' ' '                                \
| sed 's/ /,/; s/ /p/'                       \
| sed -n -f - infile

Объяснение

  • Сначала sed вызов передает infile и находит первое вхождение foo и все последующие случаи bar.
  • Эти адреса затем формируются в новое sed сценарий с двумя вызовами sed и один tr. Вывод третьего sed [start_address],[end_address]p, без скобок.
  • Заключительный вызов sed передачи infile снова, печатая найденные адреса и все промежуточное.
3
27.01.2020, 20:10

Если входной файл подходит удобно к памяти, сохраните это простым.

Если входной файл огромен, можно использовать csplit разломать его на кусочки в первом foo и в каждом последующем bar затем соберите части. Части называют piece-000000000, piece-000000001, и т.д. Выберите префикс (здесь, piece-) это не столкнется с другими существующими файлами.

csplit -f piece- -n 9 - '%foo%' '/bar/' '{*}' <input-file

(В системах не-Linux необходимо будет использовать большое количество в фигурных скобках, например. {999999999}, и передача -k опция. То число является количеством bar части.)

Можно собрать все части с cat piece-*, но это даст Вам все после первого foo. Поэтому удалите ту последнюю часть сначала. Начиная с имен файлов, произведенных csplit не содержите специальные символы, можно работать их, не принимая специальной меры предосторожности заключения в кавычки, например, с

rm $(echo piece-* | sed 's/.* //')

или эквивалентно

rm $(ls piece-* | tail -n 1)

Теперь можно присоединиться ко всем частям и удалить временные файлы:

cat piece-* >output
rm piece-*

Если Вы хотите удалить части, поскольку они связываются для сохранения дискового пространства, сделайте это в цикле:

mv piece-000000000 output
for x in piece-?????????; do
  cat "$x" >>output; rm "$x"
done
2
27.01.2020, 20:10

Я сделал бы это с небольшой остротой Perl.

cat <<EOF | perl -ne 'BEGIN { $/ = undef; } print $1 if(/(foo.*bar)/s)'
A line
like
foo
this 
foo
bar
something
something else
foo
bar
and
the
rest
EOF

урожаи

foo
this 
foo
bar
something
something else
foo
bar
4
27.01.2020, 20:10
  • 1
    Если бы это было гольфом кода, то Вы могли бы использовать E вместо e и -00777 вместо $/ бит (см. perlrun (1)). Который сократил бы его к: perl -0777 -nE 'say /(foo.*bar)/s', все еще вид читаемых. –  Thor 12.09.2012, 18:51
  • 2
    я не знал об этих флагах! Я уверен настолько особенно -0[octal] найдет, что это - путь в моем рабочем процессе! Спасибо за это –  user1146332 12.09.2012, 18:57

Вот другой способ с sed :

sed '/foo/,$!d;H;/bar/!d;s/.*//;x;s/\n//' infile

Он добавляет каждую строку в / foo /, $ диапазон (строки ! вне этого диапазона выбраны d ) до H старое пространство. Строки, не соответствующие полосе , затем удаляются. В совпадающих строках пространство шаблонов очищается, e x заменяется пространством удержания, и первая пустая строка в пространстве шаблонов удаляется.

При большом вводе и небольшом количестве появлений бара это должно быть (намного) быстрее, чем перенос каждой линии в пространство паттернов и затем каждый раз проверять пространство паттернов для бара .
Объяснение:

sed '/foo/,$!d                     # delete line if not in this range
H                                  # append to hold space
/bar/!d                            # if it doesn't match bar, delete 
s/.*//                             # otherwise empty pattern space and
x                                  # exchange hold buffer w. pattern space then
s/\n//                             # remove the leading newline
' infile

Конечно, если это файл (и он умещается в памяти), вы можете просто запустить:

 ed -s infile<<'IN'
.t.
/foo/,?bar?p
q
IN

, потому что ed может искать вперед и назад.
Вы даже можете прочитать вывод команды в текстовый буфер, если ваша оболочка поддерживает подстановку процесса:

printf '%s\n' .t. /foo/,?bar?p q | ed -s <(your command)

или, если нет, с помощью gnu ed :

printf '%s\n' .t. /foo/,?bar?p q | ed -s '!your command'
1
27.01.2020, 20:10

Использование любого awk в любой оболочке в любой системе UNIX и без одновременного чтения всего файла или входного потока в память:

$ awk '
    f {
        rec = rec $0 ORS
        if (/bar/) {
            printf "%s", rec
            rec = ""
        }
        next
    }
    /foo/ { f=1; rec=$0 ORS }
' file
foo
this
foo
bar
something
something else
foo
bar
0
27.01.2020, 20:10

Grep тоже может (хорошо, GNU grep):

<infile grep -ozP '(?s)foo.*bar' | tr '\0' '\n'

<infile grep -ozP '        #  call grep to print only the matching section (`-o`)
                           #  use NUL for delimiter (`-z`) (read the whole file).
                           #  And using pcre regex.
(?s)foo.*bar               #  Allow the dot (`.`) to also match newlines.
' | tr '\0' '\n'           #  Restore the NULs to newlines.

Для ввода из тела вопроса:

$ <infile grep -ozP '(?s)foo.*bar' | tr '\0' '\n'
foo
this 
foo
bar
something
something else
foo
bar
0
27.01.2020, 20:10

Теги

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