Поиск и замена на sed при наличии точек и подчеркиваний

#linux #command-line #sed

#linux #командная строка #sed

Вопрос:

Как мне заменить foo. на foo_ , если sed просто запущен

 sed 's/foo./foo_/g' file.php
  

не работает.

Комментарии:

1. Не могли бы вы показать нам несколько строк, file.php в которых замена не работает должным образом?

Ответ №1:

Экранируйте . :

 sed 's/foo./foo_/g' file.php
  

Пример:

 ~$ cat test.txt 
foo.bar
~$ sed 's/foo./foo_/g' test.txt 
foo_bar
  

Комментарии:

1. Спасибо! .. мне не нужно экранировать » » в «foo «?

2. Ознакомьтесь со страницей руководства по редактированию (1) в разделе «Регулярные выражения», чтобы узнать, что можно использовать в левой и правой части выражения. Кроме того, взгляните на regex(7) для объяснения регулярных выражений POSIX.2.

Ответ №2:

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

 bash --version  # Ubuntu Lucid (10.04)
  

GNU bash, версия 4.1.5(1)-релиз (x86_64-pc-linux-gnu)

Заменяет все символы тире:

 echo aa.bb.cc | sed s/./-/g
# --------
  

Заменяет точки тире:

 echo aa.bb.cc | sed s/[.]/-/g
# aa-bb-cc
  

С добавлением начальных символов в поиске работает escape.

 echo foo. | sed s/foo./foo_/g  # works
# foo_
  

Помещение точки в набор символов, конечно, тоже работает.

 echo foo. | sed s/foo[.]/foo_/g  # also works
# foo_
  

Комментарии:

1. Вы пытаетесь избежать точки в оболочке, поэтому sed обрабатывает ее как «любой символ». Попробуйте, echo foo8 | sed s/foo./foo_/g и вы все равно получите foo_ . Чтобы предотвратить экранирование оболочкой, используйте кавычки: echo aa.bb.cc | sed 's/./-/g' даст aa-bb-cc ;

Ответ №3:

Замените точку символом

 sed 's/foo./foo_/g' file.php
  

Если вы считаете сочетание / и запутанным, вы можете использовать другой символ-разделитель

 sed 's#foo.#foo_#g
  

Второй символ после s может быть любым, и sed будет использовать этот символ в качестве разделителя.

Комментарии:

1. Не знаком с sed , но действительно ли последний / необходим во 2-м примере, где # используется в качестве разделителя?

2. @binaryLV: Спасибо — это не требуется.

Ответ №4:

Вам нужно экранировать точку — неэкранированная точка будет соответствовать любому символу после foo .

 sed 's/foo./foo_/g'
  

Ответ №5:

Что касается меня, sed 's/foo./foo_/g' работает. Но вы также можете попробовать:

 sed -e 's/foo./foo_/g'
  

и

 sed -e "s/foo\./foo_/g"
  

и

 sed 's/foo[.]/foo_/g'