Mac os sed замена

Обновлено: 02.07.2024

Я использую эту команду для поиска и замены "\n" на фактические новые строковые символы:

но результат: hellongoodbye. он просто заменяет "\n" на "n", а не на новую строку. Это делает то же самое с /t, где он оставит "t", а не вкладку.

Обновление

Я пробовал обе команды, которые предложил @hek2mgl:

Хотя они могут работать с Linux, с MAC OS я получил следующую ошибку:

Не знаю, почему я не могу заставить это работать. Спасибо заранее.

ОТВЕТЫ

Ответ 1

С помощью BSD/macOS sed , чтобы использовать новую строку в заменяющей строке вызова функции s , вы должны использовать \ -экранированную фактическую новую строку - escape-последовательность \n там не поддерживается (в отличие от части регулярного выражения вызова).

Либо: просто вставьте фактическую строку новой строки:

Или: используйте ANSI C-quoted string ( $'. ' ) для сращивания в новой строке ( $'\n' ; работает в bash , ksh или zsh ):

GNU sed , напротив, распознает \n в строках замещения; читайте дальше для всестороннего обзора различий между этими двумя реализациями.

Различия между GNU sed (Linux) и BSD/macOS sed

macOS использует версию BSD sed [1] которая во многом отличается от версии GNU sed , которая поставляется с дистрибутивами Linux.

Их общий знаменатель - это функциональность, определяемая POSIX: см. спецификацию POSIX sed .

самый переносимый подход использует только функции POSIX, однако ограничивает функциональность:

  • Примечательно, что POSIX указывает поддержку только для основных регулярных выражений, которые имеют множество ограничений (например, поддержка | (чередование) вообще отсутствует, прямая поддержка + и ? ) и различные требования к экранированию.
    • Предостережение: GNU sed (без -r ), поддерживает \| , \+ и \? , который НЕ ПОДЛЕЖИТ POSIX; используйте --posix для отключения (см. ниже).
    • (обе версии): используйте только параметры -n и -e (в частности, не используйте -e или -r , чтобы включить поддержку расширенных регулярных выражений)
    • GNU sed : добавьте опцию --posix , чтобы обеспечить функциональность только POSIX (вам это не нужно, но без нее вы можете случайно не использовать функции, отличные от POSIX, не замечая: caveat: --posix не соответствует POSIX)
    • Использование только функций POSIX означает более строгие требования к форматированию (для многих удобств, доступных в GNU sed ):
      • Управляющие последовательности символов, такие как \n и \t , как правило, не поддерживаются.
      • Команды ярлыков и ветвлений (например, b ) должны сопровождаться фактической новой строкой или продолжением через отдельный параметр -e .
      • Подробнее см. ниже.

      Однако обе версии реализуют расширения стандарта POSIX:

      • какие расширения, которые они реализуют, различаются (GNU sed реализует больше).
      • даже те расширения, которые они оба реализуют, частично отличаются синтаксисом.

      Если вам нужна поддержка платформ BOTH (обсуждение различий):

      • Несовместимые функции:
        • Использование параметра -i без аргумента (обновление на месте без резервного копирования) несовместимо:
          • BSD sed : ДОЛЖНО использовать -i ''
          • GNU sed : ДОЛЖНО использовать только -i (эквивалент: -i'' ) - использование -i '' НЕ работает.
          • BSD sed : всегда добавляет новую строку на выходе, даже если строка ввода не заканчивается на один.
          • GNU sed : сохраняет статус конечной новой строки, т.е. добавляет новую строку только в том случае, если строка ввода заканчивается на одном.
          • Общие:
            • Если вы ограничиваете свои скрипты sed тем, что поддерживает BSD sed , они, как правило, будут работать и в GNU sed - с заметным исключением использования расширенных функций регулярного выражения, определенных платформой, с помощью -e . Очевидно, вы также откажетесь от расширений, характерных для версии GNU. См. Следующий раздел.

            Рекомендации по кросс-платформенной поддержке (OS X/BSD, Linux), обусловленные более строгими требованиями версии BSD:

            Обратите внимание, что я использую сокращения macOS и Linux для версий BSD и GNU sed соответственно, потому что они являются версиями запасов на каждой платформе. Тем не менее, можно установить GNU sed на macOS, например, используя Homebrew с помощью brew install gnu-sed .

            Примечание: За исключением случаев, когда используются флаги -r и -e (расширенные регулярные выражения), приведенные ниже инструкции означают запись POSIX-совместимых sed .

              Для соответствия POSIX вы должны ограничить себя POSIX BREs (основные регулярные выражения), которые, к сожалению, как следует из названия, вполне основной.
              Предостережение: не предполагайте, что поддерживаются \| , \+ и \? : в то время как GNU sed поддерживает их (если не используется --posix ), BSD sed эти функции не совместимы с POSIX.
              Хотя \+ и \? можно эмулировать в соответствии с POSIX:
              \ для \+ ,
              \ для \? ,
              \| (чередование) не может, к сожалению.

            Для более мощных регулярных выражений используйте -e (а не -r ) для поддержки ERE (расширенные регулярные выражения) (GNU sed не документирует -e , но он работает там как псевдоним -r ; более новая версия BSD sed , например, на FreeBSD 10, теперь также поддерживает -r , но версия macOS от 10.10 нет).
            Предостережение. Хотя использование -r / -e означает, что ваша команда по определению не совместима с POSIX, вы все равно должны ограничиться POSIX EREs (расширенные регулярные выражения). К сожалению, это означает, что вы не сможете использовать несколько полезных конструкций, в частности:

            • поскольку они относятся к платформе (например, \< в Linux, [[:<]] в OS X).
            • обратные ссылки внутри регулярных выражений (в отличие от "обратных ссылок" на совпадения записей в заменяющей строке вызовов функций s ), поскольку BSD sed не поддерживает их в расширенных регулярных выражениях ( но, что любопытно, делает это в базовых, где они POSIX-mandated).

            Управляющие символы, такие как \n и \t :

            В заменяющих строках, используемых с командой s , предположим, что NO escape-последовательности управляющего символа поддерживаются, поэтому снова включите контрольные символы. как литералы, как указано выше.

            То же самое для текстовых аргументов для i и a функций: не использовать последовательности символов управления - см. ниже.

            GNU sed -специфические функции отсутствуют в BSD sed в целом:

            Возможности GNU, которые вы пропустите, если вам нужно поддерживать обе платформы:

            Различные опции для сравнения и замены регулярных выражений (как в шаблонах для выбора линии, так и в первом аргументе функции s ):

            Экранирующие последовательности

            Расширения адресов, например first

            [1] Версия macOS sed старше версии на других BSD-подобных системах, таких как FreeBSD и PC-BSD. К сожалению, это означает, что вы не можете предположить, что функции, которые работают в FreeBSD, например, будут работать [то же] на macOS.

            [2] Строка с цитированием ANSI C $'\001\002\003\004\005\006\007\010\011\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177' содержит все управляющие символы ASCII, кроме \n (и NUL), поэтому вы можете использовать ее в комбинации с [:print:] для довольно надежной эмуляции [^\n] :
            '[[:print:]'$'\001\002\003\004\005\006\007\010\011\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177'']

            Ответ 2

            Это может показаться немного странным, но попробуйте:

            I.e., используйте фактическую новую строку вместо \n .

            В описании команды s там написано:

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

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

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

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

            Существует несколько версий sed, с некоторыми функциональными отличиями между ними. macOS использует версию BSD, а большинство дистрибутивов Linux поставляются с предварительно установленной GNU sed по умолчанию. Мы будем использовать версию GNU.

            Общая форма команды поиска и замены текста с использованием sed имеет следующий вид:

            • -i - По умолчанию sed записывает свой вывод в стандартный вывод. Эта опция указывает sed редактировать файлы на месте. Если указано расширение (например, -i.bak), будет создана резервная копия исходного файла.
            • s - Команда замены, вероятно, наиболее часто используемая команда в sed.
            • / / / - Разделитель символов. Это может быть любой символ, но обычно используется символ косой черты (/).
            • SEARCH_REGEX - Обычная строка или регулярное выражение для поиска.
            • REPLACEMENT - Строка замены.
            • g - Флаг глобальной замены. По умолчанию sed читает файл построчно и изменяет только первое вхождение SEARCH_REGEX в строке. Если указан флаг замены, будут заменены все вхождения.
            • INPUTFILE - Имя файла, для которого вы хотите выполнить команду.

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

            Давайте рассмотрим примеры использования команды sed для поиска и замены текста в файлах с некоторыми из его наиболее часто используемых опций и флагов.

            I используйте эту команду для поиска и замены "n " на фактические символы новой строки:

            но результат такой: hellongoodbye. он просто заменяет " n "на" n", а не фактическую новую строку. Это делает то же самое с /t, где он оставит "t", а не вкладку.

            обновление:

            Я пробовал обе команды, которые предложил @hek2mgl:

            хотя они могут работать с Linux, с MAC OS я получил следующую ошибку:

            не уверен, почему я не могу заставить это работать. Спасибо заранее.

            с BSD / macOS sed , чтобы использовать новую строку в строку замены на s вызов функции, вы должны использовать \ -сбежал фактический newline - escape sequence \n is не поддерживается там (в отличие от выражение часть Call).

            или: просто вставить фактический строки:

            или: используйте ANSI C-цитируемая строка ( $'. ' ) для соединения в новой строке ( $'\n' ; работает в bash , ksh или zsh ):

            GNU sed , напротив, тут узнать \n в строке замены; прочитайте полный обзор различий между этими двумя реализации.

            различия между GNU sed (Linux) и BSD/macOS sed

            macOS использует BSD версия sed [1] , который во многом отличается от GNU sed версия, которая поставляется с Linux дистрибутивы.

            их общий знаменатель - это функциональность, определяемая POSIX: см в POSIX sed spec.

            на самый портативный подход это используйте только функции POSIX, который, однако, ограничивает функциональные возможности:

            • Примечательно, что POSIX указывает поддержка только для basic регулярные выражения, которые имеют много ограничений (например, нет поддержки | (чередование) вообще, без прямой поддержки + и ? ) и различные экранирующие требования.
              • предостережение: GNU sed (без -r ), тут поддержка \| , \+ и \? , который не совместим с POSIX; используйте --posix отключить (см. ниже).
              • (обе версии): используйте только на -n и -e параметры (в частности, не использовать -E или -r to включите поддержку продлен регулярные выражения)
              • GNU sed добавить параметр --posix для обеспечения функциональности POSIX-only (вам это не нужно, но без этого вы можете случайно использовать функции, отличные от POSIX, не заметив; предостережение: --posix is не POSIX-совместимая)
              • использование функций только POSIX означает более строгие требования к форматированию (отказ от многих удобства в GNU sed ):
                • управляющие последовательности символов, такие как \n и \t обычно не поддерживаются.
                • метки и команды ветвления (например, b ) должны за ним следует фактический новая строка или продолжение через отдельный .
                • Подробнее см. ниже.

                , и варианты реализации расширения к стандарту POSIX:

                • что расширения, которые они реализуют отличается (GNU sed больше реализует).
                • даже те расширения они и реализовать частично отличаются синтаксисом.

                Если вам нужно поддержать обе платформы (обсуждение различия):

                • несовместимо функции:
                  • использование -i опции без аргумент (обновление на месте без резервного копирования) несовместимо:
                    • BSD sed : должны использовать -i ''
                    • GNU sed : необходимо использовать только -i (эквивалент: -i'' ) - С помощью -i '' не работает.
                    • BSD sed : всегда добавляет новую строку на выходе, даже если входная строка не заканчивается в один.
                    • GNU sed : сохраняет статус трейлинг-новой строки, т. е. он добавляет новую строку, только если входная строка заканчивается на одну.
                    • общие особенности:
                      • если вы ограничиваете свой sed скрипты к чему BSD sed поддерживает, они обычно работают в GNU sed тоже - за исключением использования платформы продлен regex особенности с -E . Очевидно, вы также откажетесь от расширений, специфичных для версии GNU. См. следующий раздел.

                      принципы кросс-платформенную поддержку (OS X / BSD, Linux), руководствуясь более строгими требованиями версии BSD:

                      обратите внимание, что я использую shorthands macOS и Linux для версий BSD и GNU sed соответственно, потому что они являются запасными версиями на каждой платформе. Тем не менее, можно установить GNU sed на macOS, например, с помощью доморощенного с brew install gnu-sed .

                      Примечание: за исключением случаев, когда -r и -E флаги (продлен regexes), приведенные ниже инструкции сводятся к написанию POSIX-совместимыми sed скрипты.

                        для соответствия POSIX вы должны ограничить себя POSIX BREs ( basic регулярные выражения), которые, к сожалению, как следует из названия, довольно просты.
                        предостережение: do не предполагайте, что \| , \+ и \? поддерживаются: в то время как GNU sed их поддерживает (если --posix используется), BSD sed не - эти функции не POSIX-совместимыми.
                        В то время как \+ и \? can эмулируются в POSIX-совместимой моде:
                        \ на \+ ,
                        \ на \? ,
                        \| (попеременно) не может, к сожалению.

                      для более мощных регулярных выражений использовать -E (а не -r ) для поддержки EREs (продлен регулярные выражения) (GNU sed не документ -E , но он работает там, как псевдоним -r ; новая версия BSD sed , например, на FreeBSD 10, теперь поддержка -r , но версия macOS по состоянию на 10.10 делает не).
                      предостережение: хотя использование -r / -E означает, что команда по определению не POSIX-совместимый, вы должны еще ограничивать себя POSIX EREs (расширенные регулярные выражения). К сожалению, это означает, что вы не сможете использовать несколько полезных конструкций, в частности:

                      то же самое для текст аргументы до i и a функции: не используйте последовательности управляющих символов - см. под.

                      GNU sed особенности отсутствует в BSD sed всего:

                      GNU функции, которые вы пропустите, если вам нужно поддерживать обе платформы:

                      различные regex-параметры сопоставления и подстановки (как в шаблонах для выбора строки, так и в первом аргументе s функция):

                      Escape-последовательности

                      адрес расширениями, например first

                      [1] macOS sed версия старше чем версия на других BSD-подобных системах, таких как FreeBSD и PC-BSD. К сожалению, это означает, что вы не можете предположить, что функции, которые работают во FreeBSD, например, будут работать [то же самое] на macOS.

                      [2] строка с кавычками ANSI $' 1 2 3 4 5 6 7013456701234567012345677' содержит все символы управления ASCII, кроме \n (и NUL), поэтому вы можете использовать его в сочетании с [:print:] для довольно надежной эмуляции [^\n] :
                      '[[:print:]'$' 1 2 3 4 5 6 7013456701234567012345677'']

                      это может показаться немного странным, но попробуйте:

                      И. Е., используйте фактический новая строка вместо \n .

                      в описании s команда там, она говорит:

                      кроме того, в описании -i опция, она говорит, что расширение не является необязательным, и что если вы не хотите, вы должны указать пустой аргумент. Так что в конце концов все имеет смысл!

                      Как использовать sed для поиска и замены строки в файлах

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

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

                      Найти и заменить строку на sed

                      Существует несколько версий sed , с некоторыми функциональными различиями между ними. macOS использует версию BSD, и большинство дистрибутивов Linux поставляются с sed предварительно установленной GNU по умолчанию. Мы будем использовать версию GNU.

                      Общая форма поиска и замены текста sed принимает следующую форму:

                      • -i - По умолчанию sed записывает свой вывод на стандартный вывод. Эта опция говорит sed редактировать файлы на месте. Если указано расширение (например, -i.bak), будет создана резервная копия исходного файла.
                      • s - Команда замены, вероятно, наиболее используемая команда в sed.
                      • / / / - разделитель персонажа. Это может быть любой символ, но обычно используется / символ косой черты ( ).
                      • SEARCH_REGEX - Обычная строка или регулярное выражение для поиска.
                      • REPLACEMENT - Строка замены.
                      • g - Глобальный флаг замены. По умолчанию sed файл читает построчно и изменяет только первое вхождение SEARCH_REGEX строки. Если указан флаг замены, все случаи будут заменены.
                      • INPUTFILE - Имя файла, для которого вы хотите выполнить команду.

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

                      Давайте посмотрим примеры того, как использовать sed команду для поиска и замены текста в файлах с некоторыми из его наиболее часто используемых опций и флагов.

                      В демонстрационных целях мы будем использовать следующий файл:

                      Если вы опустите g флаг, будет заменен только первый экземпляр строки поиска в каждой строке:

                      С глобальным флагом замены sed заменяет все вхождения шаблона поиска:

                      Как вы могли заметить, в предыдущем примере подстрока foo внутри foobar строки также заменяется. Если это нежелательное поведение, используйте выражение word-boundery ( \b ) на обоих концах строки поиска. Это гарантирует, что отдельные слова не совпадают.

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

                      Если вы хотите найти и заменить строку, содержащую символ-разделитель ( / ), вам нужно использовать обратную косую черту ( \ ), чтобы избежать косой черты. Например , чтобы заменить /bin/bash с /usr/bin/zsh вы будете использовать

                      Более простой и читаемый вариант - использовать другой символ-разделитель. Большинство людей используют вертикальную черту ( | ) или двоеточие ( : ), но вы можете использовать любой другой символ:

                      Вы также можете использовать регулярные выражения. Например, чтобы найти все 3-значные числа и заменить их строкой, которую number вы используете:


                      Еще одна полезная функция sed - вы можете использовать символ амперсанда, & который соответствует согласованному шаблону. Персонаж может быть использован несколько раз.

                      Например, если вы хотите добавить фигурные скобки <> вокруг каждого трехзначного числа, введите:


                      И последнее, но не менее важное: всегда полезно сделать резервную копию при редактировании файла с помощью sed . Для этого просто предоставьте расширение -i опции. Например, чтобы отредактировать file.txt и сохранить исходный файл, как file.txt.bak вы бы использовали:


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

                      Рекурсивный поиск и замена

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

                      Следующая команда будет рекурсивно искать файлы в текущем рабочем каталоге и передавать имена файлов в sed .


                      Чтобы избежать проблем с файлами, содержащими пробел в их именах, используйте -print0 опцию, которая указывает find печатать имя файла, за которым следует нулевой символ и направлять вывод в sed использование xargs -0 :

                      Чтобы исключить каталог, используйте -not -path опцию. Например, если вы заменяете строку в локальном git-репо, чтобы исключить все файлы, начинающиеся с точки ( . ), используйте:


                      Если вы хотите искать и заменять текст только в файлах с определенным расширением, вы должны использовать:


                      Другой вариант - использовать grep команду для рекурсивного поиска всех файлов, содержащих шаблон поиска, а затем передать имена файлов по адресу sed :

                      Вывод

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

                      Чтобы узнать о более sed команд, опции и флаги посетить GNU СЭД руководство и Grymoire СЭД учебник .

                      Читайте также: