Как заменить все знаки доллара перед всеми переменными внутри строки в двойных кавычках на sed? - PullRequest
0 голосов
/ 24 февраля 2019

У меня проблемы с заменой переменных, которые находятся внутри строк в bash.Например, я хочу заменить

"test$FOO1=$FOO2" $BAR

на:

"test" .. FOO1 .. "=" .. FOO2 .. "" $BAR

Я пытался:

sed 's/\$\([A-Z0-9_]\+\)\b/" .. \1 .. "/g'

Но я не хочу заменять переменные одинаковымипуть вне строк в двойных кавычках, например:

if [ $VARIABLE = 1 ]; then

Должен быть заменен просто

if VARIABLE then

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

Справочная информация:
Я хочу конвертировать скрипт bash в скрипт Lua .

Я знаю, что это будет нелегкопреобразуйте все возможные сценарии оболочки таким образом, но я хочу заменить все базовые языковые конструкции на команды Lua и заменить все переменные и условные выражения.Автоматизация здесь сэкономит много времени при ручном переводе bash на Lua

Ответы [ 4 ]

0 голосов
/ 06 марта 2019

с использованием групповых и рекурсивных

sed -e ':a' -e 's/^\(\([^"]*\("[^"]*"\)*\)*\)\("[^$"]*\)[$]\([A-Z0-9_]\{1,\}\)/\1\4 .. \5 .. /;t a'
  1. изолировать в строке от предыдущей части с помощью ^\(\([^"]*\("[^"]*"\)*\)*\) в группе 1
  2. выбрать содержимое переменной в строке, выделенной с помощью s\("[^$"]*\)[$]\([A-Z0-9_]\{1,\}\)'в группе 4 (префикс) и 5 ​​(имя переменной)
  3. измените, как вы хотите, с помощью \1\4 .. \5 ..
  4. повторите эту операцию, когда происходят изменения :a и t a

с помощью gnu sed вы можете уменьшить команду до (нет -e, необходимой для назначения метки a):

sed ':a;s/^\(\([^"]*\("[^"]*"\)*\)*\)\("[^$"]*\)[$]\([A-Z0-9_]\{1,\}\)/\1\4 .. \5 .. /;t a'

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

0 голосов
/ 03 марта 2019

Это может сработать для вас (GNU sed):

sed -E ':a;s/^([^"]*("[^"$]*"[^"]*)*"[^"$]*)\$([^" ]*) /\1" .. \3  .. " /;ta;s/^([^"]*("[^"$]*"[^"]*)*"[^"$]*)\$([^"]*)"/\1" .. \3/;ta' file

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

Сначала удалите ноль или более символов, которые не являются двойными кавычками с началастрока.

Во-вторых, исключите строки в двойных кавычках, которые не содержат символа интереса (TCOI), например $, за которым следует ноль или более символов, которые не являются двойными кавычками, ноль или более раз.

В-третьих, исключите двойные кавычки, за которыми следуют ноль или более символов, которые не являются двойными кавычками или TCOI, т.е. $.

Следующий символ (если он существует) должен быть TCOI.Сгруппируйте всю коллекцию строк ранее в обратной ссылке \1.

После TCOI может быть сгруппировано одно или несколько условий.В приведенном выше примере первое условие - когда за переменной (начиная с TCOI) следует пробел.Второе условие - когда за переменной следует непосредственно ".Следовательно, это влечет за собой две команды подстановки, команду ta, переходящую к циклу, идентифицированному a, когда подстановка прошла успешно.

NB Ситуацию if [ $VARIABLE = 1 ]; then можно обработать в одном и том же месте, здесь [ - это открывающая двойная кавычка, а ] - это закрывающая двойная кавычка.

PS TCOI был $, и это также метасимвол в регулярном выражении, представляющий конец строки, поэтому он должен бытьнапример, \$

PPS Не забудьте также указать [ и ].Если цитирование не ваше, заключите символ в [x], где x - это символ для кавычки.

РЕДАКТИРОВАТЬ:

sed -E ':a;s/^([^"]*("[^"$]*"[^"]*)*"[^"$]*)\$([[:alnum:]]*)/\1" .. \3  .. "/;ta' file

Поскольку исходный пример был заменен на OPВот решение, основанное на новом примере.

0 голосов
/ 03 марта 2019

лексер bash для оболочки!?

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

Чтение язык являетсяработа для консистентного лексера не для sed , ни какого-либо регулярного выражения инструмента, основанного !!!

См. GNU Bison , Berkeley Yacc (byacc) .

Вы можете взглянуть на источники , чтобы увидеть, как читаются скрипты!

СохранениеТаким образом, вы быстро перейдете к большому сценарию, а затем к неразрешимым проблемам.

0 голосов
/ 27 февраля 2019

Это с GNU awk для RS, RT и gensub () с несколькими символами показывает один из способов разделения, а затем манипулирования строк в кавычках (в RT) и без кавычек (в $ 0) в качестве отправной точки:

$ cat tst.awk
BEGIN { RS="\"[^\"]*\""; ORS="" }
{
    $0 = gensub(/\[\s+[$]([[:alnum:]_]+)\s+=\s+\S+\s+];/,"\\1","g",$0)
    RT = gensub(/[$]([[:alnum:]_]+)"/,"\" .. \\1","g",RT)
    RT = gensub(/[$]([[:alnum:]_]+)/,"\" .. \\1 .. \"","g",RT)
    print $0 RT
}

$ awk -f tst.awk file
"count: " .. FOO .. " times " .. BAR
if VARIABLE then

Вышеуказанное было выполнено для этого входного файла:

$ cat file
"count: $FOO times $BAR"
if [ $VARIABLE = 1 ]; then

ПРИМЕЧАНИЕ: этот подход сопоставления строк с регулярными выражениями всегда будет наилучшим усилием на основе предоставленных примеров, вам потребуется язык оболочкиПарсер, чтобы сделать работу надежно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...