Я пытался написать команду sed, в которой, если она находит двоеточие без окружающих пробелов, она помещает один пробел до и после двоеточия, то есть abc: def
будет преобразован в abc: def
. Я делаю так:
echo "abc:def" | sed -e 's/[^\s]\+:[^\s]\+/ : /g'
вывод по-прежнему abc: def
, как мне это сделать? что не так с моей командой выше?
\s
означает, что пространство в sed
не является переносимым — например, в реализациях POSIX ваше выражение не будет соответствовать, например. (GNU sed, в режиме posix):
$ echo "abc:def" | sed --posix -e 's/[^\s]\+:[^\s]\+/ : /g'
abc:def
Однако, если ваше выражение совпало , оно не будет делать то, что вы хотите, поскольку оно заменит всю последовательность, например. (GNU sed, в режиме, отличном от posix):
$ echo "abc:def" | sed -e 's/[^\s]\+:[^\s]\+/ : /g'
:
Вероятно, вам нужно что-то вроде s/\([^[:blank:]]\):\([^[:blank:]] \)/\1 : \2/
например
$ echo "abc:def" | sed -e 's/\([^[:blank:]]\):\([^[:blank:]]\)/\1 : \2/g'
abc : def
[Насколько я понимаю, оператор повторения \+
- который также не переносим - не нужен.]
Попробуйте:
echo "abc:def" | sed 's@\([^\s]\):\([^\s]\)@\1 : \2@g'
Я тестировал это с GNU sed, но не уверен насчет BSD sed.
Вам нужны группы захвата, если вы хотите сохранить части исходного совпадения, что и делают \(...\)
, \1
и \2
. Кроме того, вам не нужен квалификатор +
, поскольку все, что вам нужно, это непосредственные соседи.