SED не выполняет обработку выражений слева направо?

Я пробовал следующий оператор SED (sedex1) в seddy.dev: sed '/^$/d ; s/^[ \t]*// ; s/[ \t]*$// ; /::/N ; s/::/: / ; s/\n//'

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

Моя конечная цель — использовать это в Applescript в macOS. Нашей команде приходится обрабатывать подобный текст много раз в день (из форм регистрации клиентов), и нам нужен быстрый и безболезненный способ сделать это. мы думаем о pbcopy и pbpaste, но, очевидно, мы доберемся до этого, как только возьмем под контроль SED.

Использование этой команды SED (sedex1) для этого входного текста (in1):

thingOne::
some text for thingOne

thingTwo::
    some text for thingTwo

thingThree::

some text for thingThree

thingFour::

    some text for thingFour

Я получаю этот выходной текст (out1):

thingOne: some text for thingOne
thingTwo:     some text for thingTwo
thingThree: 
some text for thingThree
thingFour: 
some text for thingFour

но я пытаюсь получить этот вывод (wantedText):

thingOne: some text for thingOne
thingTwo: some text for thingTwo
thingThree: some text for thingThree
thingFour: some text for thingFour

Если я использую те же шаблоны SED, но в два этапа, все будет вести себя так, как ожидалось. в частности, запустив это (sedex2): sed '/^$/d ; s/^[ \t]*// ; s/[ \t]*$//'

на in1 производит этот вывод (out2):

thingOne::
some text for thingOne
thingTwo::
some text for thingTwo
thingThree::
some text for thingThree
thingFour::
some text for thingFour

а затем, используя это (out2) в качестве входных данных, эта команда SED (sedex3) делает все остальное: sed '/::/N ; s/::/: / ; s/\n//'

получение желаемого конечного результата (wantedText).

Что я не понимаю и/или упускаю из sedex1, что он не дает желаемого результата (wantedText), когда те же самые шаблоны, используемые последовательно в sedex2, а затем в sedex3, действительно создают WantText?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В основном вы делаете следующее:

  1. Сначала мы обрабатываем пустые строки и обрезку пробелов:
sed '/^$/d; s/^[ \t]*//; s/[ \t]*$//'
  1. Затем соединяем строки и корректируем двоеточия:
sed '/::/N; s/::/: /; s/\n//'
  • При объединении пространство шаблонов может вести себя по-разному. Давайте попробуем объединить логику таким образом, чтобы обеспечить ее последовательную обработку.

Предлагаемая команда sed

  • Есть много способов написать это регулярное выражение, исправление вашей первой команды будет следующим:
sed '/^$/d; s/^[ \t]*//; s/[ \t]*$//; /::/N; s/::/: /; s/\n[ \t]*/ /'
  1. /^$/d;: Удалить пустые строки.
  2. s/^[ \t]*//;: удалите ведущие пробелы из каждой строки.
  3. s/[ \t]*$//;: удалите конечные пробелы из каждой строки.
  4. /::/N;: добавить следующую строку к текущей, если текущая строка содержит ::.
  5. s/::/: /;: Замените :: на :.
  6. s/\n[ \t]*/ /: замените новую строку и все последующие пробелы одним пробелом.

спасибо за ваш ответ @YassineLbk, но результаты, которые я получаю с помощью вашей команды, не показывают желаемого результата. Я протестировал предложенную вами команду на seddy.dev и sed.js.org и получил тот же результат, что и в исходной формулировке задачи, а именно out1. я что-то упускаю?

tfloatcp0 17.08.2024 04:06
Ответ принят как подходящий

Это может сработать для вас (GNU sed):

sed ':a;/::\s*/{x;s//: /p;x;h;d};/\S/H;$!d;g;ba' file

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

Строки накопления помещаются в пространство удержания, заголовок этих строк будет содержать ::, а последующие непустые строки добавляются.

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

Эзотерическое улучшение вышеуказанного решения:

sed '/::\s*/{x;s//: /p;x;h;d};/\S/H;$!d;G;D' file

Альтернативное непрозрачное решение:

sed '/\n/!{/\S/H;$!d;x;D};s/::\s*/: /;P;D' file

Да, действительно! Это отлично справляется со своей задачей, большое спасибо.

tfloatcp0 17.08.2024 10:42

Конечно, разбор этого — моя следующая задача, и я открыто признаю, что это выглядит немного устрашающе. Но эй, вот как мы узнаем такие счастливые дни! :)

tfloatcp0 17.08.2024 10:45

@tfloatcp0 простой способ проанализировать sed — использовать опцию отладки --d и изучить выходные данные.

potong 17.08.2024 10:56

сделаю, спасибо.

tfloatcp0 17.08.2024 11:27

Другие вопросы по теме

Не могу получить *только* желаемый результат от команды awk
Как я могу написать сценарий Apple, который перемещает мышь в определенное положение после простоя?
Создание нескольких книг Excel из данных CSV с использованием таблиц запросов. Почему параметры формата не вступают в силу?
Используйте Applescript для создания гиперссылки в текстовом элементе в Numbers
Apple Script для запуска приложения с правами root (часть 2)
MacOS Получение пути к файлу внутри сценария оболочки при открытии файла как приложения
Applescript Microsoft Excel вставляет скопированный диапазон с другого листа
Как сделать действие папки для просмотра папки и, если оно увидит 2+ файла с одинаковым именем файла и разным расширением, создать новую папку и переместить эти файлы в папку
Удалить раздражающие «ОК» из вывода applescript?
Как я могу получить список календарей (с UID) с помощью applescript?

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

Добавьте charset=utf-8 к строке, содержащей «текст/<любой текст», где он еще не существует
Команда «sed» возвращает «Нет такого файла или каталога» при запуске с помощью доступного сценария?
Как заменить многострочный блок кода другим, разделенным указанным символом
Как добавить статический контент в одну ячейку существующего файла CSV
Как удалить все совпадающие строки и одну после каждой из них?
Как добавить заголовки в CSV-файл, в котором уже есть несколько заголовков
Удалить строку, содержащую шаблон между определенным диапазоном строк
Sed — совместимая с Posix общая множественная вставка/добавление одной команды
Дублирование записей в текстовом файле для пустых записей до тех пор, пока не будет найдена непустая запись, а затем продолжите работу с новой записью
Как вставить символ перед строкой на одну строку выше определенного символа?