Sed — совместимая с Posix общая множественная вставка/добавление одной команды

Я хотел бы выполнить несколько вставок/добавок в одной переносимой команде sed.

В GNU sed я могу сделать что-то вроде:

sed -e '1i hi' -e '$a bye' <(seq 1 10)

Я нашел следующие работы, но я не уверен, что это правильный/лучший способ справиться с этим в sed, совместимом с Posix:

sed --posix '1{x;s/$/hi/;G};//h;${x;s/$/\nbye/}' <(seq 1 10)

--или--

sed --posix '1{x;s/$/hi/;G};${s/$/\nbye/}' <(seq 1 10)

Я не видел, чтобы кто-нибудь действительно обсуждал, как удалить пространство удержания, и предположил - это лучший способ добиться этого во всех sed, совместимых с posix?

Обновление: поскольку \n на RHS не переносимо, похоже, что он будет состоять из нескольких строк:

sed --posix '1{x;s/$/hi/;G};${s/$/\
> bye/}' <(seq 1 10)

Обновлять: Хорошо, думаю, я нашел способ добавить новую строку, удерживая ее на левой стороне - хотя это довольно некрасиво:

sed '1{G;s/\(.\)\(\n\)/hi\2\1/;};${G;s/\(.\)\(\n\)/\1\2bye/;}' <(seq 1 10)

или это, немного лучше:

sed '1{G;s/\([^\n]*\)\(\n\)/hi\2\1/;};${G;s/\(\n\)/\1bye/;}' <(seq 1 10)

Ответ. Установлено на версии расширения параметров Потонга, выглядит posix-совместимым:

sed --posix $'1i\\hi\n;$a\\bye' <(seq 1 10)

Предпочтителен один вкладыш

\n в замену не переносной; это разрешено только в регулярном выражении
jhnc 15.07.2024 16:05

Да, я понимаю - согласно sed.sourceforge.io/grabbag/tutorials/sedfaq.txt мне нужно было бы разместить его на нескольких строках, чтобы встроить новую строку в целом.

Adam D. 15.07.2024 16:11
eval "$(printf 'newline = "\n"')"; sed '...'"${newline}"'...' ... или sed "$(printf '...\n...')" ... (необходимо экранировать другие метасимволы строки формата printf)
jhnc 15.07.2024 16:29

sed отлично подходит для s/old/new в отдельных строках, для всего остального (т. е. каждый раз, когда вы говорите о «удержании пробела» или используете инструкции sed, отличные от «s», «g» и «p»), просто используйте awk для ясности, простоты, портативности, удобства сопровождения и т. д. и т. п.

Ed Morton 15.07.2024 18:36

@Ed Да, вероятно, его нелегко поддерживать, если вы заблудились в некоторых менее известных командах. Я считаю, что с вставкой/добавлением/удалением справиться довольно легко - HhxgG неплохи, когда вы зацикливаетесь на обмене пространствами удержания/шаблона, но большинство людей с ними не знакомы.

Adam D. 16.07.2024 03:40

@АдамД. Частично я считаю, что даже если вставка/добавление/удаление и HhxgG не так уж и плохи, как только вы осмысливаете обмен местами удержания/шаблона, их все равно лучше избегать, поскольку одна и та же функциональность проще, понятнее, легче поддерживать/ Enhance и более переносимый в awk, а awk и sed являются обязательными инструментами POSIX, поэтому, если у вас есть sed, у вас также есть awk.

Ed Morton 16.07.2024 14:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
71
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

GNUism в первой команде заключается в том, что i и a принимают строку, которая будет вставлена ​​в одну строку, тогда как POSIX требует, чтобы они находились в разных строках. Это должно соответствовать:

sed -e '1i \
hi' -e '$a \
bye' <(seq 1 10) 

или

sed '1i \
hi
$a \
bye' <(seq 1 10) 

Выглядит хорошо, думаю, я пытался удержать это в одной строке. В нескольких строках, возможно, также можно было бы опустить -e sed --posix '1i \ hi $a \ bye' <(seq 1 10)

Adam D. 15.07.2024 16:05

@АдамД. Пока hi находится на отдельной строке ($a на новой строке), да

Benjamin W. 15.07.2024 16:14

Да, я так и писал, но комментарии схлопываются. Спасибо, похоже, потребуется многострочная обработка.

Adam D. 15.07.2024 16:16

К сожалению, MacOS не поддерживает опцию --posix, но в остальном, похоже, она работает и на Mac.

tripleee 15.07.2024 16:39

@tripleee Да, --posix просто для того, чтобы заставить GNU sed отвергать GNUisms, позвольте мне удалить это...

Benjamin W. 15.07.2024 17:29

Могу ли я с уважением предложить вам вместо этого рассмотреть Awk?

awk 'BEGIN { print "hi" } 1; END { print "bye" }' file

У меня тоже было предложение по Perl, но оказалось, что perl -i~ -pe 'BEGIN { print "hi\n"; } END { print "bye\n"; }' poo не добавляет hi и bye к poo (!)

tripleee 15.07.2024 16:45
awk, наверное, лучше для этого, но я пытаюсь ограничить количество зависимостей - уже имею дело с w/sed в разных местах.
Adam D. 16.07.2024 03:27

@АдамД. чтобы ограничить зависимости, вам следует везде использовать awk вместо sed, поскольку, как и sed, но в отличие от Perl, Python, Ruby и т. д., awk также является обязательным инструментом POSIX и может делать все, что sed (и grep, seq, tr, wc, и многие другие инструменты обработки текста), как правило, с более простым, понятным, портативным и простым в расширении/поддержании синтаксисом, но обратное неверно.

Ed Morton 16.07.2024 14:03

@ЭдМортон @АдамД. awk является даже в BusyBox, как я предполагаю на основании требований @AdamD., которые также могут быть индикатором пригодности в среде POSIX/Embedded/ограниченной.

ppenguin 17.07.2024 11:52
Ответ принят как подходящий

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

sed $'1i\\hi\n$a\\bye' file

или

sed '1G;1s/\(.*\)\(.\)/hi\2\1/;$G;$s/$/bye/' file

или

sed '1h;1s/.*/hi/p;1g;$a\bye' file

или

sed 'H;1h;$!d;s/.*/hi/;G;a\bye' file

или

sed '1{x;s/^/hi/p;x};${p;s/.*/bye/}' file

Спасибо дружище! Первое, это то, что я искал..

Adam D. 16.07.2024 14:54

Играли в гольф до: sed $'1ihi\n;$abye' <(seq 1 10)

Adam D. 16.07.2024 15:24

Поскольку перевод строки взят из оболочки, от ; также можно избавиться. Я поставил двойную обратную косую черту, чтобы сделать решение совместимым с posix.

potong 17.07.2024 11:40

👍- Да, это, наверное, гольф-макс.

Adam D. 17.07.2024 23:58

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