Неопределенная команда 's' с 's/([\^][^])//g'

Я пытаюсь найти символы каретки (^) в моем файле и удалить их и последующие символы, когда они существуют. Я запускаю это в Bash.

Каждый раз, когда я пытаюсь запустить sed для этого:

sed -i 's/([\^][^])//g' myfile.txt

Я получаю ошибку ниже:

sed: -e expression #1, char 14: unterminated `s' command

Есть идеи?

3 ответа

Решение

Выражение [^] незакончен, потому что сед использует ] следуя карат ^ как отрицательный список символов, отсутствует ] ([^]]) необходимо. Но это будет соответствовать закрытию ]ничего, что вы хотите (я считаю).

Я полагаю, что вы намереваетесь соответствовать карат: \^, А то что ты написал ([\^]) также не будет соответствовать карат. Это будет соответствовать либо обратной косой черты \ или карат ^:

$  echo 'abc\def^ghij'
abc\def^ghij

$ echo 'abc\def^ghij' | sed 's/[\^]//g'
abcdefghij

Но даже это не то, что вы написали:

найти любой карат (^) ... и удалить их и последующий символ, когда они существуют

Если предполагаемый последующий символ - любой символ, используйте: \^.
Если последующим символом является любой символ, который не является каратом, используйте: \^[^\^]
Или просто: \^[^^]

$ echo 'ab\cd^^ef^gh' | sed 's/\^[^^]//g'
ab\cd^fh

То есть:

sed -i 's/\^[^^]//g' infile

Это то, что вы ищете?

Секция [^] не класс персонажа; ] скобка является первым символом класса отрицанных символов, а код ищет следующий ] (лечить все )//g как часть класса символов) и не найдя затем маркер конца, что приводит к ошибке.

В положительном случае вы можете использовать [][] искать закрывающую квадратную скобку или открытую квадратную скобку в классе символов. Отрицательная версия будет [^][],

С помощью [^]] остановит сообщение об ошибке - тогда вам просто нужно исправить регулярное выражение, чтобы сделать то, что вы собираетесь.

Обратите внимание, что по умолчанию круглые скобки интерпретируются как круглые скобки, а не как метасимволы группировки (вам понадобится \(…\) для этого). На самом деле, нет необходимости в группировке, поэтому скобки исключены из обсуждения ниже.

Исправление к вашему регулярному выражению умеренно ясно, когда я перечитал вопрос. Вы пытаетесь удалить каретку и следующий символ после нее. Это немного двусмысленно; если каретка находится в конце строки (поэтому следующий символ - это новая строка), следует ли также удалять новую строку? Я собираюсь предположить, что нет. Я также предполагаю, что ^^ должны быть удалены; вопрос говорит "любые символы каретки (^) в моем файле и удалять их и последующий символ", не говоря "если следующий символ тоже не является кареткой". Понятно, что регулярные выражения могут быть изменены, если любое из предположений неверно (хотя с предположением о новой строке сложнее справиться, но с большим запасом).

sed 's/\^.\{0,1\}//g'

Это ищет каретку (избегая классов персонажей) и следующий символ, если он есть, на той же строке - \{0,1\} нотация означает 0 или 1 повторение предыдущего выражения.

Если ваш вариант sed поддерживает расширенные регулярные выражения, вы сможете использовать sed -E 's/\^.?//g' (Mac OS X и BSD) или sed -r 's/\^.?//g' (ГНУ).

POSIX не поддерживает классы символов, состоящие только из каретки. [\^] нотация - это класс символов, состоящий из обратной косой черты и каретки ("или каретка"?):

$ echo 'abc\de^Afg' | sed 's/[\^].\{0,1\}//g'
abcefg
$ echo 'abc\de^Afg' | sed 's/\^.\{0,1\}//g'
abc\defg
$ echo 'abc\de^Afg' | sed -E 's/\^.?//g'
abc\defg
$ echo 'abc\de^Afg' | /opt/gnu/bin/sed 's/[\^].\{0,1\}//g'
abcefg
$ echo 'abc\de^Afg' | /opt/gnu/bin/sed 's/\^.\{0,1\}//g'
abc\defg
$ echo 'abc\de^Afg' | /opt/gnu/bin/sed -r 's/\^.?//g'
abc\defg
$

(Plain sed это Mac OS X sed; /opt/gnu/bin/sed это GNU sed.)

найти любые символы в карате (^) в моем файле и удалить их и последующий символ

Давайте возьмем этот тестовый файл:

$ cat myfile.txt 
a^2 b^2 c

Я считаю, что это делает то, что вы хотите:

$ sed  's/\^.\?//g' myfile.txt
a b c

Как Вам известно, ^ обычно является регулярным выражением Нам нужно избежать этого, чтобы мы могли соответствовать буквальному ^, В регулярных выражениях . соответствует любому персонажу. Таким образом, \^. соответствует каретке, за которой следует любой символ. Регулярное выражение \^.\? соответствует каретке и следующему символу, если есть следующий символ.

Другие вопросы по тегам