Поиск и замена слов в файлах linux

Недавно столкнулся с проблемой, мне нужно было найти определенные слова в файлах и заменить их на нужный мне текст. Немного поискав в интернете, я нашел как это сделать, по этому решил записать заметку  «Поиск и замена слов в файлах linux», пригодится как мне так и другим пользователям. Это можно сделать командой find и  grep с некоторыми параметрами.

Простой поиск с использованием grep:

#·grep -rl 'фраза_для_поиска' /var/папка_для_поиска_(путь_к_файлу)

Поиск и замена текста в файлах:

#·grep 'текст_который_нужно_искать' -P -R -I -l ·* | xargs sed -i 's/текст_который_нужно_искать/текст_который_нужно_заменить/g'

Удаление определенного символа из файлов

#·find . -type f -print0 | xargs -0 perl -i -pe 's/xEFxBBxBF//'

Нужно символы прописывать в уникоде, если правильно понял.

Как заменить слово в файлах при рекурсивном поиске Linux?

#·find -type f -name *.py -exec sed -i -r 's/text_1/text_2/g' {} ;

Этой строкой мы ищем во всех файлах с разрешением *.py от текущей директории строку text_1 и заменяя  ее наtext_2, так же можно использовать regexp выражения.

Еще примеры

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

$ find . | xargs grep "require_once"

Получаем:

13 lines
(captain@Macbook)()(03:32 PM Fri Feb 20)
└─(~/My works/network)(203 files, 2576b)> find . | xargs grep "if ( ! current_user_can( 'manage_sites' ) )"
grep: .: Is a directory
./site-info.php:if ( ! current_user_can( 'manage_sites' ) )
./site-info.php-r:if ( ! current_user_can( 'manage_sites' ) )
./site-info.php-r-r:if ( ! current_user_can( 'manage_sites' ) )
./site-new.php:if ( ! current_user_can( 'manage_sites' ) )
./site-new.php-r:if ( ! current_user_can( 'manage_sites' ) )
./site-settings.php:if ( ! current_user_can( 'manage_sites' ) )
./site-themes.php:if ( ! current_user_can( 'manage_sites' ) )
./site-themes.php-r:if ( ! current_user_can( 'manage_sites' ) )
./sites.php:if ( ! current_user_can( 'manage_sites' ) )
./sites.php-r:if ( ! current_user_can( 'manage_sites' ) )

или для конкретных файлов:

$·find . -name ".php" | xargs grep "require_once"

Выполнить замену можно еще следующим образом:

#·sed -i -r 's/require_once/Я махал это еще разделать/g' * ;

Допустим, Вам необходимо выполнить замену целой строки ( закомментировать какую либо функцию, добавив // перед самой функцией), то можно это сделать:

$·sed -i -r 's/Я это еще раз cделал///Ya eto vipolnil/g' * ;

Экранируем спец символы и заменяем на любую другую строку, для этого:

#·sed -i -r "s|if ( ! current_user_can( 'manage_sites' ) )|//if ( ! current_user_can( 'manage_sites' ) )|" *

Данная команда заменит одну строку на другую во всех файлах.

Упрощенная версия ее:

#·sed -i 's/(^.*current_user_can.*manage_sites.*)$///1/' site-info.php

Можно удалить многострочное содержание текста который находиться, например между //###==### и //###==###

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

#·sed -i 'N;N;s|//###==###n.*n//###==###||;P;D' some_file.php

Я делал сканирование maldet и нашел много вредоносного кода, по этому, я удалил его так:

# cat /tmp/maldet.sorted |awk '{print $3}'|xargs -n1 sed -i 'N;N;s|//###==###n.*n//###==###||;P;D'

Еще пример:

TMP_File="/opt/zabbix/cloudwatch/tmp.txt" Get_AWS_ACCESS_KEY_ID=$(cat $TMP_File | grep -E 'AccessKeyId'| awk '{print $2}'| cut -d '"' -f2) sed -i -e "s/^aws_access_key_id=.*$/aws_access_key_id=$Get_AWS_ACCESS_KEY_ID/g" /opt/zabbix/cloudwatch/conf/awscred

Как заменить всю строку на другую? Та вот так можно:

$ gsed -i "s#.*44444.dkr.ecr.us-west-2.amazonaws.com/docker-openjdk11-base:latest#FROM gitlab-registry.my_company.com/docker-openjdk11-base:latest#g" tmp.txt

Или тоже самое, но через переменные:

5 lines
$ export AWS_ECR_IMAGE=444.dkr.ecr.us-west-2.amazonaws.com/docker-openjdk11-base:latest
$ export GITLAB_REGISTRY_IMAGE=gitlab-registry.my_company.com/docker-openjdk11-base:latest
$ gsed -i "s#.*$AWS_ECR_IMAGE#FROM $GITLAB_REGISTRY_IMAGE#g" tmp.txt

-===Пример===-

Предположим, имеется файл и в нем находится:

One.Two.Three

Но по заданию, нужно чтобы было —  Three.Two.One

Для этого, выполним:

$·gsed -i -e "s/(One).(Two).(Three)/3.2.1/g" test.txt

PS: О долбанном SED-е я расскажу очень не скоро, он меня реально бесит и злит. Кто ее придумал, реальный сука ДЖЕДАЙ 😀

Делаю замену версий в Terraform так:

$ gsed -ri 's|( required_version =) .*|1 "~> 0.14"|g' *

Делаем замену другим способом:

3 lines
$ rpl -iqR require_once slogniy_etot_SED *
$ rpl -iqR slogniy_etot_SED я Али Баба *

ПРИМЕЧАНИЕ! Утилиту rpl необходимо установить.

Centos/RedHat/Fedora:

Debian/Ubuntu/Mint:

MacOS:

Устанавливаем HOMEBREW.

Выполняем установку:

Я попозже постараюсь привести еще примеров и рассказать о утилите в своей новой статье.

Когда не удобно искать файлы в консольном режиме и есть GUI интерфейс, то можно воспользоваться утилитой regexxer.
Debian/Ubuntu/Mint:

или

CentOS/RedHat/Fedora:

Очень простая и хорошая утилита, я сам ею пользовался и тестировал на своей виртуальной машине на Debian.

На этом моя короткая заметка  «Поиск и замена слов в файлах linux» завершена и готова к использованию.

Было ли это полезно?

0 / 0