Bash вставить строку в файл в определенном месте
При работе с текстовыми файлами вам часто нужно искать и заменять строки текста в одном или нескольких файлах.
sed является s Tream ред itor. Он может выполнять базовые операции с текстом над файлами и входными потоками, такими как конвейеры. С помощью sed вы можете искать, находить и заменять, вставлять и удалять слова и строки. Он поддерживает базовые и расширенные регулярные выражения, которые позволяют сопоставлять сложные шаблоны.
В этой статье мы поговорим о том, как найти и заменить строки с помощью sed . Мы также покажем вам, как выполнить рекурсивный поиск и замену.
Найти и заменить строку с помощью sed
Существует несколько версий sed с некоторыми функциональными различиями. macOS использует версию BSD, в то время как большинство дистрибутивов Linux поставляются с предустановленной по умолчанию GNU sed . Мы будем использовать версию GNU.
Общая форма поиска и замены текста с помощью sed имеет следующий вид:
Рекомендуется заключать аргумент в кавычки, чтобы метасимволы оболочки не расширялись.
Давайте посмотрим, как мы можем использовать команду sed для поиска и замены текста в файлах некоторыми из наиболее часто используемых параметров и флагов.
В демонстрационных целях мы будем использовать следующий файл:
Если флаг g опущен, заменяется только первый экземпляр строки поиска в каждой строке:
С флагом глобальной замены sed заменяет все вхождения шаблона поиска:
Как вы могли заметить, подстрока foo внутри строки foobar также заменена в предыдущем примере. Если это нежелательное поведение, используйте выражение границы слова ( b ) на обоих концах строки поиска. Это гарантирует, что частичные слова не совпадают.
Чтобы сделать совпадение с шаблоном нечувствительным к регистру, используйте флаг I В приведенном ниже примере мы используем флаги g и I
Если вы хотите найти и заменить строку, содержащую символ-разделитель ( / ), вам нужно будет использовать обратную косую черту ( ), чтобы избежать косой черты. Например, чтобы заменить /bin/bash на /usr/bin/zsh вы должны использовать
Вы также можете использовать регулярные выражения. Например, чтобы найти все трехзначные числа и заменить их строковым number вы должны использовать:
Еще одна полезная функция sed заключается в том, что вы можете использовать символ амперсанда & который соответствует сопоставленному шаблону. Персонаж можно использовать несколько раз.
Например, если вы хотите добавить фигурные скобки <> вокруг каждого трехзначного числа, введите:
И последнее, но не менее важное: всегда рекомендуется делать резервную копию при редактировании файла с помощью sed . Для этого просто укажите расширение файла резервной копии для параметра -i . Например, чтобы отредактировать file.txt и сохранить исходный файл как file.txt.bak вы должны использовать:
Чтобы убедиться, что резервная копия создана, выведите список файлов с помощью команды ls :
Рекурсивный поиск и замена
Иногда может потребоваться рекурсивный поиск в каталогах файлов, содержащих строку, и замена строки во всех файлах. Это можно сделать с помощью таких команд, как find или grep для рекурсивного поиска файлов в каталоге и передачи имен файлов в sed .
Следующая команда будет рекурсивно искать файлы в текущем рабочем каталоге и передавать имена файлов в sed .
Чтобы избежать проблем с файлами, содержащими пробелы в своих именах, используйте параметр -print0 , который указывает find напечатать имя файла, за которым следует нулевой символ, и xargs -0 вывод в sed используя xargs -0 :
Чтобы исключить каталог, используйте параметр -not -path . Например, если вы заменяете строку в локальном репозитории git, чтобы исключить все файлы, начинающиеся с точки ( . ), Используйте:
Если вы хотите искать и заменять текст только в файлах с определенным расширением, вы будете использовать:
Выводы
Хотя это может показаться сложным и сложным, поначалу поиск и замена текста в файлах с помощью sed очень просты.
Чтобы узнать больше о sed команд, опций и флагов, посетить GNU СЭД руководство и Grymoire СЭД учебник .
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
В этой статье объясняется, как записать текст в файл в Bash с помощью операторов перенаправления и команды tee .
Запись в файл с использованием операторов перенаправления
В Bash перенаправление вывода позволяет вам захватить вывод команды и записать его в файл.
Общий формат перенаправления и записи вывода в файл следующий:
- Оператор перенаправления > записывает вывод в указанный файл. Если файл существует, он обрезается до нулевой длины. В противном случае файл создается. Будьте особенно осторожны при использовании этого оператора, так как вы можете перезаписать важный файл.
- Оператор перенаправления >> добавляет вывод в указанный файл. Если файл не существует, он создается.
Чтобы предотвратить перезапись существующих файлов, включите опцию «noclobber» с помощью встроенной команды set :
>| оператор позволяет вам переопределить параметр Bash «noclobber»
Оператор >> добавляет вывод в конец файла, а не перезаписывает файл:
Используйте команду printf если вы хотите создать сложный вывод:
Если вы хотите записать несколько строк в файл, используйте перенаправление документа Here (Heredoc).
Например, вы можете передать содержимое команде cat и записать его в файл:
Чтобы добавить строки, замените > на >> перед именем файла:
Вы можете записать вывод любой команды в файл:
Вывод команды date будет записан в файл.
Запись в файл с помощью команды tee
Команда tee читает из стандартного ввода и записывает как в стандартный вывод, так и в один или несколько файлов одновременно.
По умолчанию команда tee перезаписывает указанный файл, как и оператор > . Чтобы добавить вывод в файл, вызовите команду с параметром -a ( --append ):
Чтобы записать текст в несколько файлов, укажите файлы в качестве аргументов команды tee :
Еще одно преимущество команды tee заключается в том, что вы можете использовать ее вместе с sudo и записывать в файлы, принадлежащие другим пользователям. Чтобы добавить текст в файл, в который у вас нет прав на запись, добавьте sudo перед tee :
Выходные данные команды echo передаются как входные в tee , который повышает разрешения sudo и записывает текст в файл.
Выводы
В Linux для записи текста в файл используйте операторы перенаправления > и >> или команду tee .
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
В Bash есть несколько способов добавить текст в файл. Эта статья объясняет некоторые из них.
Добавить в файл с помощью оператора перенаправления ( >> )
Перенаправление позволяет захватывать выходные данные команды и отправлять их в качестве входных данных в другую команду или файл. Оператор перенаправления >> добавляет вывод в указанный файл.
Существует ряд команд, которые вы можете использовать для вывода текста на стандартный вывод и перенаправления его в файл, причем наиболее часто используются команды echo и printf .
Чтобы добавить текст в файл, укажите имя файла после оператора перенаправления:
При использовании с параметром -e команда echo интерпретирует экранированные символы обратной косой черты, такие как новая строка n :
Чтобы получить более сложный вывод, используйте команду printf которая позволяет вам указать форматирование вывода:
Например, вы можете передать содержимое команде cat и добавить его в файл:
Вы можете добавить вывод любой команды в файл. Вот пример с командой date :
При добавлении к файлу с использованием перенаправления будьте осторожны, чтобы не использовать оператор > для перезаписи важного существующего файла.
Добавить в файл с помощью команды tee
По умолчанию команда tee перезаписывает указанный файл. Чтобы добавить вывод в файл, используйте tee с параметром -a ( --append ):
Если вы не хотите, чтобы tee выводил данные на стандартный вывод, перенаправьте его на /dev/null :
Преимущество использования команды tee перед оператором >> заключается в том, что tee позволяет добавлять текст сразу в несколько файлов и записывать в файлы, принадлежащие другим пользователям, вместе с sudo .
Чтобы добавить текст в файл, в который у вас нет прав на запись, добавьте sudo перед tee как показано ниже:
tee получает вывод команды echo , повышает разрешения sudo и записывает в файл.
Чтобы добавить текст в несколько файлов, укажите файлы в качестве аргументов команды tee :
Выводы
В Linux для добавления текста в файл используйте оператор перенаправления >> или команду tee .
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
В прошлый раз мы говорили о функциях в bash-скриптах, в частности, о том, как вызывать их из командной строки. Наша сегодняшняя тема — весьма полезный инструмент для обработки строковых данных — утилита Linux, которая называется sed. Её часто используют для работы с текстами, имеющими вид лог-файлов, конфигурационных и других файлов.
Если вы, в bash-скриптах, каким-то образом обрабатываете данные, вам не помешает знакомство с инструментами sed и gawk. Тут мы сосредоточимся на sed и на работе с текстами, так как это — очень важный шаг в нашем путешествии по бескрайним просторам разработки bash-скриптов.
Сейчас мы разберём основы работы с sed, а так же рассмотрим более трёх десятков примеров использования этого инструмента.
Основы работы с sed
Утилиту sed называют потоковым текстовым редактором. В интерактивных текстовых редакторах, наподобие nano, с текстами работают, используя клавиатуру, редактируя файлы, добавляя, удаляя или изменяя тексты. Sed позволяет редактировать потоки данных, основываясь на заданных разработчиком наборах правил. Вот как выглядит схема вызова этой команды:
По умолчанию sed применяет указанные при вызове правила, выраженные в виде набора команд, к STDIN . Это позволяет передавать данные непосредственно sed.
Вот что получится при выполнении этой команды.
Простой пример вызова sed
В данном случае sed заменяет слово «test» в строке, переданной для обработки, словами «another test». Для оформления правила обработки текста, заключённого в кавычки, используются прямые слэши. В нашем случае применена команда вида s/pattern1/pattern2/ . Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. Sed, выполняя эту команду, просмотрит переданный текст и заменит найденные в нём фрагменты (о том — какие именно, поговорим ниже), соответствующие pattern1 , на pattern2 .
Выше приведён примитивный пример использования sed, нужный для того, чтобы ввести вас в курс дела. На самом деле, sed можно применять в гораздо более сложных сценариях обработки текстов, например — для работы с файлами.
Ниже показан файл, в котором содержится фрагмент текста, и результаты его обработки такой командой:
Текстовый файл и результаты его обработки
Здесь применён тот же подход, который мы использовали выше, но теперь sed обрабатывает текст, хранящийся в файле. При этом, если файл достаточно велик, можно заметить, что sed обрабатывает данные порциями и выводит то, что обработано, на экран, не дожидаясь обработки всего файла.
Выполнение наборов команд при вызове sed
Для выполнения нескольких действий с данными, используйте ключ -e при вызове sed. Например, вот как организовать замену двух фрагментов текста:
Использование ключа -e при вызове sed
К каждой строке текста из файла применяются обе команды. Их нужно разделить точкой с запятой, при этом между окончанием команды и точкой с запятой не должно быть пробела.
Для ввода нескольких шаблонов обработки текста при вызове sed, можно, после ввода первой одиночной кавычки, нажать Enter, после чего вводить каждое правило с новой строки, не забыв о закрывающей кавычке:
Вот что получится после того, как команда, представленная в таком виде, будет выполнена.
Другой способ работы с sed
Чтение команд из файла
Если имеется множество команд sed, с помощью которых надо обработать текст, обычно удобнее всего предварительно записать их в файл. Для того, чтобы указать sed файл, содержащий команды, используют ключ -f :
Вот содержимое файла mycommands :
Вызовем sed, передав редактору файл с командами и файл для обработки:
Результат при вызове такой команды аналогичен тому, который получался в предыдущих примерах.
Использование файла с командами при вызове sed
Флаги команды замены
Внимательно посмотрите на следующий пример.
Вот что содержится в файле, и что будет получено после его обработки sed.
Исходный файл и результаты его обработки
Команда замены нормально обрабатывает файл, состоящий из нескольких строк, но заменяются только первые вхождения искомого фрагмента текста в каждой строке. Для того, чтобы заменить все вхождения шаблона, нужно использовать соответствующий флаг.
Схема записи команды замены при использовании флагов выглядит так:
Выполнение этой команды можно модифицировать несколькими способами.
- При передаче номера учитывается порядковый номер вхождения шаблона в строку, заменено будет именно это вхождение.
- Флаг g указывает на то, что нужно обработать все вхождения шаблона, имеющиеся в строке.
- Флаг p указывает на то, что нужно вывести содержимое исходной строки.
- Флаг вида w file указывает команде на то, что нужно записать результаты обработки текста в файл.
Вызов команды замены с указанием позиции заменяемого фрагмента
Тут мы указали, в качестве флага замены, число 2. Это привело к тому, что было заменено лишь второе вхождение искомого шаблона в каждой строке. Теперь опробуем флаг глобальной замены — g :
Как видно из результатов вывода, такая команда заменила все вхождения шаблона в тексте.
Глобальная замена
Флаг команды замены p позволяет выводить строки, в которых найдены совпадения, при этом ключ -n , указанный при вызове sed, подавляет обычный вывод:
Как результат, при запуске sed в такой конфигурации на экран выводятся лишь строки (в нашем случае — одна строка), в которых найден заданный фрагмент текста.
Использование флага команды замены p
Воспользуемся флагом w , который позволяет сохранить результаты обработки текста в файл:
Сохранение результатов обработки текста в файл
Хорошо видно, что в ходе работы команды данные выводятся в STDOUT, при этом обработанные строки записываются в файл, имя которого указано после w .
Символы-разделители
Представьте, что нужно заменить /bin/bash на /bin/csh в файле /etc/passwd . Задача не такая уж и сложная:
Однако, выглядит всё это не очень-то хорошо. Всё дело в том, что так как прямые слэши используются в роли символов-разделителей, такие же символы в передаваемых sed строках приходится экранировать. В результате страдает читаемость команды.
К счастью, sed позволяет нам самостоятельно задавать символы-разделители для использования их в команде замены. Разделителем считается первый символ, который будет встречен после s :
В данном случае в качестве разделителя использован восклицательный знак, в результате код легче читать и он выглядит куда опрятнее, чем прежде.
Выбор фрагментов текста для обработки
До сих пор мы вызывали sed для обработки всего переданного редактору потока данных. В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:
- Задать ограничение на номера обрабатываемых строк.
- Указать фильтр, соответствующие которому строки нужно обработать.
Обработка только одной строки, номер который задан при вызове sed
Второй вариант — диапазон строк:
Обработка диапазона строк
Кроме того, можно вызвать команду замены так, чтобы файл был обработан начиная с некоей строки и до конца:
Обработка файла начиная со второй строки и до конца
Для того, чтобы обрабатывать с помощью команды замены только строки, соответствующие заданному фильтру, команду надо вызвать так:
По аналогии с тем, что было рассмотрено выше, шаблон передаётся перед именем команды s .
Обработка строк, соответствующих фильтру
Тут мы использовали очень простой фильтр. Для того, чтобы в полной мере раскрыть возможности данного подхода, можно воспользоваться регулярными выражениями. О них мы поговорим в одном из следующих материалов этой серии.
Удаление строк
Утилита sed годится не только для замены одних последовательностей символов в строках на другие. С её помощью, а именно, используя команду d , можно удалять строки из текстового потока.
Вызов команды выглядит так:
Мы хотим, чтобы из текста была удалена третья строка. Обратите внимание на то, что речь не идёт о файле. Файл останется неизменным, удаление отразится лишь на выводе, который сформирует sed.
Удаление третьей строки
Если при вызове команды d не указать номер удаляемой строки, удалены будут все строки потока.
Вот как применить команду d к диапазону строк:
Удаление диапазона строк
А вот как удалить строки, начиная с заданной — и до конца файла:
Удаление строк до конца файла
Строки можно удалять и по шаблону:
Удаление строк по шаблону
При вызове d можно указывать пару шаблонов — будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними:
Удаление диапазона строк с использованием шаблонов
Вставка текста в поток
С помощью sed можно вставлять данные в текстовый поток, используя команды i и a :
- Команда i добавляет новую строку перед заданной.
- Команда a добавляет новую строку после заданной.
Теперь взглянем на команду a :
Как видно, эти команды добавляют текст до или после данных из потока. Что если надо добавить строку где-нибудь посередине?
Тут нам поможет указание номера опорной строки в потоке, или шаблона. Учтите, что адресация строк в виде диапазона тут не подойдёт. Вызовем команду i , указав номер строки, перед которой надо вставить новую строку:
Команда i с указанием номера опорной строки
Проделаем то же самое с командой a :
Команда a с указанием номера опорной строки
Обратите внимание на разницу в работе команд i и a . Первая вставляет новую строку до указанной, вторая — после.
Замена строк
Команда c позволяет изменить содержимое целой строки текста в потоке данных. При её вызове нужно указать номер строки, вместо которой в поток надо добавить новые данные:
Замена строки целиком
Если воспользоваться при вызове команды шаблоном в виде обычного текста или регулярного выражения, заменены будут все соответствующие шаблону строки:
Замена строк по шаблону
Замена символов
Команда y работает с отдельными символами, заменяя их в соответствии с переданными ей при вызове данными:
Замена символов
Используя эту команду, нужно учесть, что она применяется ко всему текстовому потоку, ограничить её конкретными вхождениями символов нельзя.
Вывод номеров строк
Если вызвать sed, использовав команду = , утилита выведет номера строк в потоке данных:
Вывод номеров строк
Потоковый редактор вывел номера строк перед их содержимым.
Если передать этой команде шаблон и воспользоваться ключом sed -n , выведены будут только номера строк, соответствующих шаблону:
Вывод номеров строк, соответствующих шаблону
Чтение данных для вставки из файла
Выше мы рассматривали приёмы вставки данных в поток, указывая то, что надо вставить, прямо при вызове sed. В качестве источника данных можно воспользоваться и файлом. Для этого служит команда r , которая позволяет вставлять в поток данные из указанного файла. При её вызове можно указать номер строки, после которой надо вставить содержимое файла, или шаблон.
Вставка в поток содержимого файла
Тут содержимое файла newfile было вставлено после третьей строки файла myfile .
Вот что произойдёт, если применить при вызове команды r шаблон:
Использование шаблона при вызове команды r
Содержимое файла будет вставлено после каждой строки, соответствующей шаблону.
Пример
Представим себе такую задачу. Есть файл, в котором имеется некая последовательность символов, сама по себе бессмысленная, которую надо заменить на данные, взятые из другого файла. А именно, пусть это будет файл newfile , в котором роль указателя места заполнения играет последовательность символов DATA . Данные, которые нужно подставить вместо DATA , хранятся в файле data .
Решить эту задачу можно, воспользовавшись командами r и d потокового редактора sed:
Замена указателя места заполнения на реальные данные
Как видите, вместо заполнителя DATA sed добавил в выходной поток две строки из файла data .
Итоги
Сегодня мы рассмотрели основы работы с потоковым редактором sed. На самом деле, sed — это огромнейшая тема. Его изучение вполне можно сравнить с изучением нового языка программирования, однако, поняв основы, вы сможете освоить sed на любом необходимом вам уровне. В результате ваши возможности по обработке с его помощью текстов будет ограничивать лишь воображение.
На сегодня это всё. В следующий раз поговорим о языке обработки данных awk.
Читайте также: