Почему я должен выйти из regex символов в sed, который будет интерпретироваться как regex символы?

Это может быть сделано как это:

rename 's/xvg$/txt/' *.xvg

Шаблон шарика гарантирует это только *.xvg файлы затронуты.

11
15.09.2013, 02:30
2 ответа

Это вызвано тем, что sed использование POSIX BREs (Основные Регулярные выражения) в противоположность EREs (Расширенные регулярные выражения) Вы, вероятно, привыкли к от Perl или друзей.

От sed(1) страница справочника:

REGULAR EXPRESSIONS
       POSIX.2 BREs should be supported, but they aren't completely because of
       performance problems.  The \n sequence in a regular expression  matches
       the newline character, and similarly for \a, \t, and other sequences.

Соответствующая кавычка из вышеупомянутой ссылки:

Основные Регулярные выражения или разновидность BRE стандартизируют разновидность, подобную той, используемой традиционным UNIX grep команда. Это - в значительной степени самая старая разновидность регулярного выражения, все еще используемая сегодня. Одна вещь, которая отделяет эту разновидность, состоит в том, что большинство метасимволов требует, чтобы обратная косая черта дала метасимволу свою разновидность. Большинство других разновидностей, включая POSIX ДО, использует обратную косую черту для подавления значения метасимволов.

Заключенный в кавычки дословно из комментария Craig Sanders:

Обратите внимание, что в GNU sed, по крайней мере, можно сказать sed использовать расширенный regexps с-r или - опция строки regexp-расширенной-команды. Это полезно, если Вы не хотите уродовать свой sed сценарий с чрезмерным выходом.

14
27.01.2020, 19:57
  • 1
    Обратите внимание, что в GNU sed, по крайней мере, можно сказать sed использовать расширенный regexps с -r или --regexp-extended параметр командной строки. Это полезно, если Вы не хотите уродовать свой sed сценарий с чрезмерным выходом. –  cas 15.09.2013, 03:54
  • 2
    @CraigSanders спасибо за это. Добавленный к ответу. –  Joseph R. 15.09.2013, 17:39
  • 3
    @CraigSanders, другой sed реализации (когда они действительно поддерживают EREs, главным образом BSDs) имеют тенденцию использовать -E для этого вместо этого (который имеет намного больше смысла, так как это - та же опция что касается grep. Почему GNU sed выбрал -r тайна мне). –  Stéphane Chazelas 18.09.2013, 09:16
  • 4
    да, тайна мне также. Имело бы больше смысла использовать-E. и затем добавлять-F,-G, и-P для соответствия GNU grep. Простофиля IMO извлекла бы выгоду из того же РЕ args также... или по крайней мере,-P. –  cas 18.09.2013, 14:56

Это по историческим причинам.

Regexp были сначала представлены в Unix в ed утилита в начале 70-х. Хотя ed был на основе qed чья реализация те же авторы поняли более сложный regexp, ed только понятый ^, $, [...], ., * и \ выйти изо всего вышеупомянутого.

Теперь, когда потребность иметь больше операторов возникла, путь, как должны были находить, представлял их, не повреждая обратную совместимость. Если сценарий раньше использовал s ed команда как s/foo() {/foo (var) {/g заменять все экземпляры foo() { с foo(var) { и Вы представили a ( или { оператор, который повредил бы тот сценарий.

Однако никакой сценарий не сделал бы s/foo\(\) {/foo\(var\) {/, потому что это совпадает с s/foo() {/foo(var) {/ и не было никакой причины выйти ( поскольку это не было оператором RE. Так представление нового \( или \{ оператор не повреждает обратную совместимость, как это очень вряд ли повредит существующий сценарий с помощью более старого синтаксиса.

Так, это - то, что было сделано. Позже, \(...\) был добавлен первоначально только для s ed команда, чтобы сделать вещи как s/foo\(.\)/\1bar/ и позже как grep '\(.\)\1' (но подоконник не вещи как \(xx\)*).

В UnixV7 (1979, поэтому почти десятилетие спустя), новая форма регулярных выражений была добавлена в новом egrep и awk утилиты назвали расширенное регулярное выражение (так как они - новые инструменты, нет никакой обратной совместимости, которая будет повреждена). Наконец, это предоставило функциональность, доступную в древнем Ken Thompson qed (оператор чередования |, группировка (..)*) и добавил несколько операторов как + и ? (но не имел backref функции основных регулярных выражений).

Позже добавленный BSDs \< и \> (и к BRE и к ДО), и SysV добавил \{ и \} к BREs только.

Это только в намного позже, чем { и } были добавлены к ДО, такой обратной совместимостью повреждения. Не все добавили его. Например, GNU awk пока версия 4.0.0 (2011) не поддерживала { если не вызвано в режим соответствия POSIX.

когда GNU grep был записан в начале 90-х, это добавило всех положительных героев и от BSD и от SysV (как \<, {) и вместо того, чтобы иметь два отдельных regexp синтаксиса и механизм для BRE и ДО, реализовал те же операторы в обоих, только дубликаты BRE (, ?, {, + должны предшествоваться с обратной косой чертой (чтобы быть совместимым с другими реализациями BRE). Вот почему можно сделать .\+ в GNU grep (хотя это не POSIX или поддерживаемый другими реализациями), и можно сделать (.)\1 в GNU egrep (хотя это не POSIX или поддерживаемый многими другими реализациями включая GNU awk).

Добавление \x операторы не являются единственным способом добавить больше операторов обратно совместимым способом. Например, perl б/У (?...). Это все еще обратно совместимо с EREs как (?=...) не допустимо в EREs, том же для .*?. vim поскольку подобные операторы сделали это по-другому путем представления \@= или .\{-} например.

12
27.01.2020, 19:57

Теги

Похожие вопросы