Как передать переменную, содержащую косые черты, в sed


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

так вот он идет...

как вы передаете переменную, содержащую косые черты в качестве шаблона для sed.

например, если у меня есть следующая переменная:

var="/Users/Documents/name/file"

Я хочу передать его sed как Итак:

sed "s/$var/replace/g" $file

однако я получаю ошибки. Как я могу обойти эту проблему?

5   51  

5 ответов:

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

sed "s~$var~replace~g" $file

чистый ответ bash: используйте расширения параметр to backslash-escape любые косые черты в переменной:

var="/Users/Documents/name/file"
sed "s/${var//\//\/}/replace/g" $file

другой способ сделать это, хотя и уродливее, чем ответ анубхавы, - это избежать всех обратных косых черт в var через другой :

var=$(echo "$var" | sed 's/\//\\//g')

тогда, это будет работать:

sed "s/$var/replace/g" $file

используя / в sed в качестве разделителя будет конфликтовать с косыми чертами в переменной при замене и в результате вы получите ошибку. Один из способов обойти это-использовать другой разделитель, который уникален от любых символов, которые находятся в этой переменной.

var="/Users/Documents/name/file"

вы можете использовать символ octothorpe, который подходит для этого случая (или любой другой символ, который не является / для удобства использования)

sed "s#$var#replace#g" 

или

  sed 's#$'$var'#replace#g'

это подходит когда переменная не содержит пробелов

или

sed 's#$"'$var'"#replace#g'

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

альтернативный разделитель работает только тогда, когда есть необходимость в поиске и замене. В случаях, когда есть необходимость удалить строки из файла на основе слова, содержащего / (например,/dev/sda1) это не сработает. Например:

var1=/dev/sda1
sed -i ":$var1:d" $file 

Я хотел бы пойти с решением, предложенным @Bolboa