Замените строку в файле на другую, где оба сохраняются в переменных

Я хочу заменить строку, найденную в файле, другой строкой, но оба имеют специальный символ (в этом примере это символ.), Например 1.0 и 2.0 .

Итак, это команда, используемая в настоящее время:

 sed -i 's/1\.0/2\.0/g' /home/user1/file1.txt 

Что делать, если 1.0 и 2.0 были сохранены в переменных $i и $j ? где i имеет значение 1.0 а j имеет значение 2.0 , как я могу поменять i на j ?

3 Solutions collect form web for “Замените строку в файле на другую, где оба сохраняются в переменных”

Вы можете просто использовать sed для исправления для вас:

 printf '%s\n' "$i" "$j" | sed 's/[]\$*&/.^[]/\\&/g;H;$!d x;y|\n|/|;s|.*|s&/g|' | sed -f - /path/to/infile 

Таким образом, это s/// ubstitution будет избегать любых / всех метасимволов BRE во вводе:

 s/[]\$*&/.^[]/\\&/g 

… путем префикса каждой обратной косой черты. Первый sed затем сохраняет копию первой строки – $i – в старом пространстве H добавляя к ней символ \n ewline. Линия $i затем выставляется, потому что она ! а не $ last. Следующая строка – строка $j – также является последней, и после того, как она получает то же самое, что и первое, она не сглажена. Вместо этого e x изменяет буферы удержания и шаблонов и работает с конкатенированными результатами. В этот момент пространство шаблонов выглядит так:

 \n1\.0\n2\.0 

… так что мы y/// переводим все \n ewlines для / slashes, s/// ubstitute .* все пространство шаблонов для & self плюс добавленные s и добавленные /g которые нас получают:

 s/1\.0/2\.0/g 

Затем он автоматически переходит во второе седло, которое читает stdin – или -f - – как его скрипт. Когда первый sed закончен и закрывает трубку между ними, второй sed начинает применять …

 s/1\.0/2\.0/g 

… для каждой строки в названном входном файле – здесь /path/to/infile .

Я написал ваш файл следующим образом:

 printf '%04s%04s%04s%04s\n' \ 0 0 -1 0 1 0 0 0 0 -1\ 0 0 1.5 2.0 1.0 0 >/tmp/temp 

Который достал мне файл вроде …

  0 0 -1 0 1 0 0 0 0 -1 0 0 1.5 2.0 1.0 0 

Затем я написал другую версию вашего скрипта:

 ii=0.0 for i in 1.0 2.0 3.0 4.0 do str2=$i printf '\033[41m## %s \033[0m\n' \ "str2 = $str2" "$ii $str2" printf %s\\n "$ii" "$str2" ii=$str2 done | sed ' s/[]\$^&*./[]/\\&/g;H;x s|^\(\n\)\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)|\ bs\5\1:i\5\1i\\\1\2\\\1\3\1:s\5\1s/\4/\5/gp;ti\5|p s

;h;d' | sed -f – /tmp/temp

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

Когда я запускаю его, результаты:

  0 0 -1 0 1 0 0 0 0 -1 0 0 1.5 2.0 2.0 0 ## str2 = 2.0 ## 1.0 2.0 1.5 3.0 3.0 0 ## str2 = 3.0 ## 2.0 3.0 1.5 4.0 4.0 0 ## str2 = 4.0 ## 3.0 4.0 1.5 4.0 4.0 0 

Строки, начинающиеся с # , окрашены в красный цвет, как я ожидаю, вы хотите, чтобы они были. sed только записывает их, когда s/// ubstitution успешно. Скрипт, который первый sed пишет для второго, выглядит так:

  bs1\.0 :i1\.0 i\ [41m## str2 = 1\.0 [0m\ [41m## 0\.0 1\.0 [0m :s1\.0 s/0\.0/1\.0/gp;ti1\.0 bs2\.0 :i2\.0 i\ [41m## str2 = 2\.0 [0m\ [41m## 1\.0 2\.0 [0m :s2\.0 s/1\.0/2\.0/gp;ti2\.0 bs3\.0 :i3\.0 i\ [41m## str2 = 3\.0 [0m\ [41m## 2\.0 3\.0 [0m :s3\.0 s/2\.0/3\.0/gp;ti3\.0 bs4\.0 :i4\.0 i\ [41m## str2 = 4\.0 [0m\ [41m## 3\.0 4\.0 [0m :s4\.0 s/3\.0/4\.0/gp;ti4\.0 

Обратите внимание, что, хотя кажется, что [ строки не экранированы, это только эффект моего терминала на выходе), который завершает прием символа сразу после \033 . Когда второй sed получает скрипт, вход подобен \033\[... но вывод, который он выводит на stdout, – это \033[...

попробуйте это: Escape all. заменяя все . to \.

 str1="$( echo -n $i | sed 's/\./\\\./g' )" 

повторите то же самое для str2, используя $ j . затем заменим следующим образом

 sed "s/$str1/$str2/g" 
  • Есть что-то вроде «xdg-close» - напротив xdg-open?
  • Как передать файлы, загруженные с помощью wget через tar?
  • Создание списка доменов с помощью httpd.conf
  • Как проверить, запрашивалась ли предыдущая команда для ввода?
  • Вставить текст по определенному номеру строки
  • printf в сценарии оболочки can not do \ x% x
  • awk: принудительное возвращение статуса?
  • Параметры Bash - Split
  • Сценарий оболочки для выполнения сеанса telnet в ser2net
  • bash myscript.sh работает в bash, но первая строка: #! / usr / bin / sh
  • Оптимизация цикла while
  • Interesting Posts

    Почему изменения в / etc / passwd не вступают в силу?

    Bash: дать построенный массив для функции в качестве списка аргументов?

    Разница между ulimit -n и / proc / $ PID / лимитами

    Spec rpm: Я хочу сделать gmake -j3

    Как скомпилировать драйвер AMD Legacy на 64-битном ядре, Linux Mint 17

    Debian 9 – разрешить ТОЛЬКО определенный IP-адрес для MongoDB

    Самый эффективный способ запуска 2 в то время как петли

    ~ / .bash_profile выполняется для не-регистрационных оболочек

    Поведение команды `du` с флагом` -L`

    Я хочу использовать переменную, объявленную внутри сеанса SSH, для локального использования в сценарии оболочки

    Какую команду использовать для поиска всех файлов / папок с разрешениями, отличными от настроек по умолчанию?

    Есть ли способ выполнять команды при вводе пользователя?

    «TeamViewer не готов. Пожалуйста, проверьте свою связь "ошибка в Fedora 25

    Есть ли способ читать строки из вывода команды?

    Важным является порядок блоков в / etc / network / interfaces? если да, то почему?

    Linux и Unix - лучшая ОС в мире.