2016-05-20 2 views
0

У меня есть файл, как это:Почему порядок замены вещей имеет значение в sed?

(paren) 
[sharp] 

И я пытаюсь заменить так:

sed "s/(/[/g" some_file.txt 

И это прекрасно работает:

[paren) 
[sharp] 

Тогда я пытаюсь заменить как это:

sed "s/[/(/g" some_file.txt 

И это дает мне ошибку:

sed: 1: "s/[/(/g": unbalanced brackets ([]) 

Я не могу найти никаких доказательств того, почему это было бы без ошибок. Почему порядок [ и ( вопрос?

спасибо.

+0

Если 'человек sed' не дает достаточно информации, то Google' sed' и прочитать любой учебник по нему. –

ответ

4

[ является частью bracket expression, который должен иметь замыкающий аналог (]).

Побег [, чтобы соответствовать буквальному [ символа:

echo "[sharp]" | sed 's/\[/(/g' 

См IDEONE demo

+1

Что касается * Почему порядок '[' и '(' matter? *, Это фактически не порядок, а то, что делает команда sed sed. Андрей описывает это, но вот мое дополнение: 's 'является действием * замены *, затем появляется * регулярный шаблон POSIX * (если у вас есть' (', он рассматривается как литерал' (', но' ['является частью выражения скобки, поэтому должно быть закрытие ']' для того, чтобы шаблон был действительным), затем * замещающий шаблон * (просто * строка *, которая может содержать обратные ссылки, но не шаблон регулярного выражения), а затем * флаг * (или * модификатор *) (здесь, 'g' - глобальная замена всех совпадений). –

2

Причина это важно потому, что вы заменяете регулярное выражение с символьной строкой. Таким образом, скобка рассматривается как символ при использовании после второй косой черты. Он рассматривается как часть недопустимого регулярного выражения при использовании между первым и вторым косой чертой.

Таким образом, в этом выражении '[' воспринимается как символ:

s/(/[/g

В этом выражении нет:

s/[/(/g

1

Первый параметр в качестве замены с СЭД должен быть регулярным выражением:
s/regex_pattern/replacement_string/

Открывающая квадратная скобка имеет особое значение в шаблоне регулярных выражений, так как это начало класса символов, например [a-z]. Вот почему вы получаете это сообщение об ошибке, которое не имеет ничего общего с порядком ваших замещений: unbalanced brackets ([])(открытый класс символов должен быть закрыт.)

Для получения буквального открытия квадратных скобок, необходимо, чтобы избежать его: \[

sed 's/\[/(/' file 

Если ваша цель состоит в том, чтобы перевести символы в другие, есть более простой способ, с помощью перевода, что позволяет избежать проблемы круговых замен:

a='(paren) 
[sharp]' 

с использованием tr

echo "$a" | tr '[]()' '()[]' 

или sed:

echo "$a" | sed 'y/[]()/()[]/'