Escape-имя файла для использования в подстановке sed - PullRequest
4 голосов
/ 09 декабря 2011

Как я могу это исправить:

abc="a/b/c"; echo porc | sed -r "s/^/$abc/"
sed: -e expression #1, char 7: unknown option to `s'

Подстановка переменной $abc выполнена правильно, но проблема в том, что $abc содержит косые черты, которые путают sed. Можно ли как-нибудь избежать этих слешей?

Ответы [ 5 ]

7 голосов
/ 09 декабря 2011

Обратите внимание, что sed(1) позволяет вам использовать разные символы для s/// разделителей:

$ abc="a/b/c"
$ echo porc | sed -r "s|^|$abc|"
a/b/cporc
$ 

Конечно, если вы идете по этому маршруту, вы должны убедиться, что выбранные вами разделители не подходят.не используется в других местах вашего ввода.

6 голосов
/ 09 декабря 2011

В руководстве GNU для sed говорится, что "Символы / могут быть равномерно заменены любым другим отдельным символом в любой заданной s-команде."

Поэтому просто используйте другой символ вместо /, например ::

abc="a/b/c"; echo porc | sed -r "s:^:$abc:"
  1. Не используйте символ, который может бытьнайдено в вашем входе. Мы можем использовать : выше, поскольку мы знаем, что вход (a/b/c/) не содержит :.

  2. Будьте осторожны с экранированием символов.

    • При использовании "" Bash будет интерпретировать некоторые символы специально, например, ` (используется для встроенного выполнения), ! (используется для доступа к истории Bash ), $ (используется для доступа к переменным).

    • При использовании '' Bash принимает все символы буквально, даже $.

    • Два подхода могут быть объединены, в зависимости от того, нужно ли вам сбежать или нет, например:

      abc="a/b/c"; echo porc | sed 's!^!'"$abc"'!'
      
3 голосов
/ 09 декабря 2011

Вам не нужно использовать / в качестве шаблона и заменить разделитель, как уже говорили вам другие. Я бы пошел с :, так как он довольно редко используется в путях (это разделитель в переменной окружения PATH). Придерживайтесь одного и используйте встроенные в оболочку функции замены строк, чтобы сделать его пуленепробиваемым, например. ${abc//:/\\:} (что означает замену всех : вхождений \: в ${abc}) в случае : в качестве разделителя.

$ abc="a/b/c"; echo porc | sed -r "s:^:${abc//:/\\:}:"
a/b/cporc
1 голос
/ 09 декабря 2011

обратная косая черта:

abc='a\/b\/c'

заполнение пространства ....

0 голосов
/ 07 сентября 2012

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

escaped_abc=$(echo $abc | sed "s/\//\\\AAA\//g" | sed "s/AAA//g")

Тройная буква A используется потому, что в противном случае прямая косая черта после ее экранирующей обратной косой черты никогда не помещается в выходной файл, независимо от того, сколько обратной косой черты вы ставите перед ней.

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