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

Необходимо включить расширенные регулярные выражения для этого:

grep -E ':[[:alnum:]]+:' ~/x.txt
4
13.03.2015, 00:29
2 ответа

Вы можете просто использовать 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старом месте, префиксовав к ней символ \newline. Строка $i затем d поднимается, потому что это ! не последняя $. Следующая строка - строка $j - тоже последняя, и после того, как к ней будет применена та же обработка, что и к первой, она будет , а не d поднята. Вместо этого она exменяет буферы удержания и буферы паттерна и работает на конкатенированных результатах. В этой точке пространство паттерна выглядит следующим образом:

\n1\.0\n2\.0

...поэтому мы y/// переводим все \newlines для / косых черт, s///ubstitute . * все шаблоны-пространства для самого и плюс готовые с и дополнительный /g, который получает нас:

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

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

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

...к каждой строке в его именованном входном файле - который здесь /путь/к/в файле.

Я написал ваш файл вот так:

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 выполнять всю обработку данных. Обратите внимание, что хотя два seds вызываются каждый, они вызываются только один раз.

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

   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

Обратите внимание, что хотя строки [ не экранируются, это просто влияние моего терминала на выход - который в результате съедает char сразу после \033. Когда второй sed получает скрипт, то входной сигнал подобен \033\[...]. , но его вывод inserts to stdout - это \033[...].

1
27.01.2020, 21:00

Попробуйте: Избежать всех. заменив все . к \.

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

Повторите одинаковую для STR2, используя $ j . Тогда замените следующим образом

sed "s/$str1/$str2/g"
1
27.01.2020, 21:00

Теги

Похожие вопросы