Как мне объединить нижнюю строку с предыдущей строкой?

Вопрос или проблема

У меня есть довольно простой файл;

15
Название главы


некоторый текст и еще немного текста
некоторый текст и еще немного текста

Я пытался получить что-то подобное

Книга: 15 Название главы


некоторый текст и еще немного текста
некоторый текст и еще немного текста

Я пытался сделать это с помощью sed с помощью этого паттерна;

sed 's/^\([[:digit:]]\+\)\n\([[:alpha:]].*$\)\n$/Книга: \1 \2\n/g'

Очевидно, это не работает из терминала, однако работает прекрасно внутри VIM версии sed.

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

Тем не менее, вы можете сопоставить одиночное целое число, добавить к нему следующую строку и работать оттуда:

$ sed -e '/^[0-9][0-9]*$/!b' -e 'N; s/\n/ /' -e 's/^/Книга: /' файл
Книга: 15 Название главы


некоторый текст и еще немного текста
некоторый текст и еще немного текста

Это пропускает (просто выводит) все строки, которые не являются целым числом. Когда обнаруживается одиночное целое число, следующая строка добавляется в конец буфера с помощью N, с разделительной новой строкой между ними. Эта новая строка заменяется пробелом с помощью s, и мы вставляем текст Книга: в начало строки.

Если вы знаете, что целое число находится на первой строке, вы можете изменить эту начальную команду с /^[0-9][0-9]*$/!b на более короткую 1!b.

Ответ или решение

Чтобы объединить строку с номером главы с последующей строкой, содержащей название главы, можно воспользоваться утилитой sed. Данная задача заключается в преобразовании определенного формата текста в другой, более удобочитаемый. В вашем случае текст выглядит следующим образом:

15
Chapter name

some text and some more text
some text and some more text

А вы хотите его преобразовать так:

Book: 15 Chapter name

some text and some more text
some text and some more text

Утилита sed предназначена для обработки текстовых файлов путем применения различных текстовых преобразований и правил. В своем первоначальном варианте вы использовали такую команду:

sed 's/^\([[:digit:]]\+\)\n\([[:alpha:]].*$\)\n$/Book: \1 \2\n/g'

Однако, эта команда не сработала из-за особенностей работы sed, которая обрабатывает ввод построчно и не может непосредственно обрабатывать символы перевода строки в выражениях. Тем не менее, существует корректный способ объединить строки, используя комбинацию команд sed.

Правильное решение может выглядеть следующим образом:

sed -e '/^[0-9][0-9]*$/!b' -e 'N; s/\n/ /' -e 's/^/Book: /' файл

Разбор команды:

  1. *`/^[0-9][0-9]$/!b** - этот шаблон проверяет, является ли текущее соответствие целым числом. Если эта строка не соответствует шаблону (то есть, не число), выполнение команды прекращается иsed` переходит к следующей строке.

  2. N; s/\n/ / – при нахождении целого числа, команда N добавляет следующую строку к текущей, объединяя их через символ новой строки. Затем s/\n/ / заменяет символ новой строки на пробел, тем самым объединяя строки.

  3. s/^/Book: / – эта команда добавляет префикс "Book: " в начале строки, что соответствует вашим требованиям.

Пример использования:

Запустив вышеуказанную команду sed, вы получите желаемый результат:

Book: 15 Chapter name

some text and some more text
some text and some more text

Дополнительные комментарии:

В тех случаях, когда вы точно знаете, что строка с целым числом находится на первой позиции, вы можете упростить первый условный оператор, заменив его на 1!b, что будет означать "пропустить, если это не первая строка".

Используя предложенное решение, вы сможете эффективно объединить строки в тексте, добиваясь нужного формата. Подобные манипуляции с текстовыми файлами часто могут быть полезны для автоматизации работы с данными.

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

Оцените материал
Добавить комментарий

Капча загружается...