Замените все экземпляры символа, если он встречается перед другим символом

Мне нужно иметь возможность экспортировать некоторые переменные из файла, чтобы я мог использовать его в моем сценарии BASH. содержимое файла выглядит примерно так:

my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers 

Сначала я попытался найти его с использованием source как есть, и получил сообщение об ошибке: command not found . Я попытался использовать export , который дал мне сообщение об ошибке: not a valid identifier .

Я думаю, что я могу экспортировать только если я изменю свою переменную от my.variable.var1 до my_variable_var1 .
Я могу это сделать, отрезая строку at = и затем заменяя все . s с _ s, а затем добавление переменных обратно.

Поэтому мой вопрос: можно ли изменить:

 my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers 

в

 my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers 

используя любой из этих крутых «один лайнер»? Хотелось бы использовать это, плюс хорошее обучение.

  • Запуск приложения из терминала
  • base10 не работает
  • Файлы TAR: перемещение файлов из подкаталогов в основной каталог
  • Как демультиплексировать аудио и знать, какой он тип?
  • Как возобновить приостановленную оболочку?
  • Невозможно использовать команду date для изменения определенного формата даты в оболочке Bash на терминале OS X
  • Полоса пропускания новой строки с входного канала
  • Как я могу отфильтровать определенные команды из многострочной истории Bash при выходе из системы?
  • 3 Solutions collect form web for “Замените все экземпляры символа, если он встречается перед другим символом”

    С sed :

     sed -e :1 -e 's/^\([^=]*\)\./\1_/;t1' 

    Это заменяет последовательность символов, кроме . в начале строки, за которой следует . по той же последовательности и _ и повторить процесс до тех пор, пока он больше не будет соответствовать.

    С awk :

     awk -F = -v OFS== '{gsub(/\./, "_", $1); print}' 

    Теперь, если правая часть = содержит символы, специальные для оболочки ( \ "$ & (); '# ~ <> …`, пробел, табуляция, другие пробелы …), вы можете захотеть цитата:

     sed "s/'/'\\\\''/g;:1"' s/^\([^=]*\)\./\1_/;t1'" s/=/='/;s/\$/'/" 

    Или:

     awk -F = -vq="'" -v OFS== ' {gsub(q, q "\\" qq) gsub(/\./, "_", $1) $2 = q $2 print $0 q}' 

    Использование bash :

     while IFS='=' read -rij; do echo "${i//./_}=$j" ; done 

    Мы использовали шаблон расширения параметра ${i//./_} для замены всех . s с _ s в имени переменной.

    Пример:

     $ cat file.txt my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers $ while IFS='=' read -rij; do echo "${i//./_}=$j" ; done <file.txt my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers 

    Вот еще одно sed :

     sed 'h;s/\./_/g;G;s/=.*=/=/' 

    Это делает только две замены, независимо от количества точек, предшествующих = so, с помощью ввода, такого как:

     my.var.an.other.var.with.many.dots=line.with.many:chars:and_numbers.and.stuff 

    результат

     my_var_an_other_var_with_many_dots=line.with.many:chars:and_numbers.and.stuff 

    Это работает нормально, когда в строке есть один символ = char (как в вашем примере ввода).
    Более общий подход, который всегда заменяет только до первого = (и только если строка содержит хотя бы одну = ), даже если в строке указано несколько символов:

     sed '/=/{ # if line matches = h # copy pattern space over the hold space s/\./_/g # replace all . with = G # append hold space content to pattern space s/=.*\n[^=]*=/=/ # replace from the first = up to the first = after }' # the newline character with a single = 

    или

     sed -e '/=/{h;s/\./_/g;G;s/=.*\n[^=]*=/=/' -e '}' 

    поэтому с входом вроде:

     my.var.with.many.dots.but.no.equal.sign.and.stuff my.var.with.many.dots=line.with.many:chars:numbers_and.stuff other.var.with.many.dots=and.with.more.than=one.equal.sign=and.stuff 

    он выводит:

     my.var.with.many.dots.but.no.equal.sign.and.stuff my_var_with_many_dots=line.with.many:chars:numbers_and.stuff other_var_with_many_dots=and.with.more.than=one.equal.sign=and.stuff 
    Interesting Posts
    Linux и Unix - лучшая ОС в мире.