Arhn - архитектура программирования

Bash sed: заменить все специальные символы (недопустимый конец диапазона)

Конечная цель — заменить строку, содержащую пароль (который может содержать любой символ) в файле:

...
passw=old#$#$@$#@%{}[]
...

У меня есть строковые переменные с заменами: (пока не обращайте внимания на двойные кавычки)

$old="passw=old#$#$@$#@%{}[]"

$new="passw=new#$#$@$#@%{}[]"

Если я использую простой sed -i "s#$old#$new#g" file.txt", он, очевидно, не работает должным образом, поскольку специальные символы нарушают синтаксис.

Чтобы это работало, мне нужно экранировать все специальные символы с помощью \, например: \[

Я пытался использовать что-то вроде этого:

esc=$("$old" | sed 's/[][`~!@#$%^&*()-_=+{}\|;:",<.>/?'"'"']/\\&/g'

Однако это дает мне следующую ошибку:

sed: -e expression #1, char42: Invalid range end

Любая помощь будет принята с благодарностью!

03.03.2017

  • Вы забыли экранировать / в тексте поиска при установке esc. 03.03.2017
  • Может есть какая-то разметка, поэтому sed игнорирует спецсимволы в переменной? 04.03.2017

Ответы:


1

Вы не добьетесь этого без правильного побега. Я пробовал sed, perl и т. д., но все они ломаются, особенно в символах {} и [].

Вы можете применить sed для одновременного экранирования всех необычных символов.
В приведенном ниже примере я экранирую все, что не является текстом (a-z и A-Z) и не является числом (0-9).

$ cat file14
passw=old#$#$@$#@%{}[]

$ old='passw=old#$#$@$#@%{}[]' && echo "$old"  #mind the single quotes.
passw=old#$#$@$#@%{}[]

$ new='passw=new$#$#$$0-.?!@#$%^&*()_+@$#@%[]{}' && echo "$new"
passw=new$#$#$$0-.?!@#$%^&*()_+@$#@%[]{}

$ old=$(sed 's/[^a-zA-Z0-9]/\\&/g' <<<"$old") && echo "$old"
passw\=old\#\$\#\$\@\$\#\@\%\{\}\[\]

$ new=$(sed 's/[^a-zA-Z0-9]/\\&/g' <<<"$new") && echo "$new"
passw\=new\$\#\$\#\$\$0\-\.\?\!\@\#\$\%\^\&\*\(\)\_\+\@\$\#\@\%\[\]\{\}

$ sed -r "s/$old/$new/" file14
passw=new$#$#$$0-.?!@#$%^&*()_+@$#@%[]{}
03.03.2017
  • Я нашел это как самый ясный подход к моей цели. Благодарю вас! 05.03.2017

  • 2

    awk на помощь!

    Обратите внимание, что замена основана на регулярном выражении, и специальные символы необходимо экранировать для строки поиска в awk, а также для строк поиска и замены в sed. Это требует предварительной обработки строк. В качестве альтернативы, если ваш входной файл структурирован, вы можете попробовать проверить равенство строк

    Например,

    $ awk -v old='old#$#$@$#@%{}[]'    \
          -v new='[]{}new#$#$@$#@%'    \
          -v key='passw=' '"^"key{line=$0; 
                                  sub(key,"",line); 
                                  if(line==old) $0=key new}1' file 
    

    работает на входном файле

    passw=old#$#$@$#@%{}[]
    some other line with old#$#$@$#@%{}[]
    

    будет генерировать

    pasw=[]{}new#$#$@$#@%
    some other line with old#$#$@$#@%{}[]
    

    вы также можете выполнить проверку на равенство для полного совпадения key=value, как показано ниже.

    $ awk -v old='old#$#$@$#@%{}[]' \
          -v new='[]{}new#$#$@$#@%' \
          -v key='passw=' '$0==key old{$0=key new}1' file
    

    или упростить путем поиска и замены строк с префиксом key=

    awk -v old='passw=old#$#$@$#@%{}[]' \
        -v new='passw=[]{}new#$#$@$#@%' \
              '$0==old{$0=new}1' file
    

    они предполагают, что ваша запись пароля находится в отдельной строке. Если это неверное предположение, вы можете установить RS и ORS на ' ' и удалить последний символ выходного файла (последний добавленный ORS). Другим решением может быть перебор полей в цикле (например, for(i=1;i<=NF;i++) if($i==old) $i=new...)

    03.03.2017
  • Спасибо за ваш ответ. Я довольно новичок в bash, однако я вижу, что это заменяет только текст внутри переменной. Мне нужно заменить часть текста внутри файла. Кстати, старая и новая части пароля не статичны. 04.03.2017
  • Я попробовал ваше решение, но выдает ошибку "awk: cmd. line:1: fatal: Invalid content of \{\}: /passw=old#$#$@$#@%{}[]/" 04.03.2017
  • Откуда взялся /? 04.03.2017
  • Понятия не имею... Ты проверял? Если в вашем тесте все работает нормально, возможно, я что-то не так сделал. 04.03.2017
  • Но опять же, странно. Посмотрите здесь, что я получаю: pastebin.com/GEMM3mHz 04.03.2017
  • Вы должны изменить только старую строку на новую, и это должны быть переменные. Спецсимволы не меняются, только альфа. 04.03.2017
  • Это означает, что каждый специальный символ после старого остается прежним, но я думаю, что это не OP (глубокое) желание. 04.03.2017
  • Тогда я, возможно, неправильно понял вопрос. Пример должен охватывать самый общий случай... 04.03.2017
  • Хотя я решил пойти с решением Джорджа, я нашел ваш ответ полезным для общих знаний! 05.03.2017
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..