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