2013-09-07 3 views
1

Конечной целью является замена всех экземпляров^NULL^на ^^. Для этого вопроса, чтобы повысить удобочитаемость, я попытаюсь заменить^NULL^на^fred ^. Вот мои тестовые данные.Замена последовательных значений в файле с разделителями

/usr/redbrick_dir $ cat temp 
a^NULL^b^c^ 
e^NULL^NULL^f^ 
g^h^i^NULL^ 

Это то, что я ожидаю от работы.

/usr/redbrick_dir $ cat temp | sed "s/\^NULL\^/\^fred\^/g" 
a^fred^b^c^ 
e^fred^NULL^f^ 
g^h^i^fred^ 

Обратите внимание, что в строке 2 заменяется только первый экземпляр^NULL ^. Однако, если я запускаю команду только с одним разделителем,

/usr/redbrick_dir $ cat temp | sed "s/NULL\^/fred\^/g" 
a^fred^b^c^ 
e^fred^fred^f^ 
g^h^i^fred^ 

Я получаю желаемые результаты. Я также получаю эти результаты, если я использую только трейлинг-разделитель. Вопрос в том, почему эта команда заменяет только первый экземпляр^NULL ^?

cat temp | sed "s/\^NULL\^/\^fred\^/g" 

Edit начинается здесь

Вот что случилось, когда я попробовал пару ответов, размещенных ниже.

cat temp | sed "s/(?<=\^)NULL(?=\^)/fred/g" 
a^NULL^b^c^ 
e^NULL^NULL^f^ 
g^h^i^NULL^ 

cat temp | sed ":a s/\^NULL^/^fred^/;ta" 
sed: 0602-417 The label :a s/\^NULL^/^fred^/;ta is greater than eight characters. 

Обязательно ознакомьтесь с ссылкой, предоставленной Utopik.

ответ

2

Почему эта команда заменяет только первый экземпляр^NULL ^?

Поскольку выражение не соответствует во второй строке второго ^NULL^, после того, как выражение находит первое ^NULL^, теперь он пытается найти совпадение в характере сразу после ^:

e^NULL^ NULL^f^ 
    ^
    it is now trying to find a match here but there is no ^NULL^ here, there is NULL^ only. 

Regex101 Demo

Я не знаю, если sed поддерживает или lookaheads Утверждения назад, но если это так, то я хотел бы сделать замену так:

cat temp | sed "s/(?<=\^)NULL(?=\^)/fred/g" 

Или в вашем случае заменить fred с пустой строкой, конечно.

2

Испытано с GNU СЭД

Первое, вы можете удалить некоторые обратную косую черту: sed "s/\^NULL^/^fred^/g" без каких-либо изменений (^ не имеет никакого значения, но при запуске регулярных выражений)

Затем СЭД будет соответствовать ^NULL^ и нет символа из этого матча можно повторно использовать для другого матча. Таким образом, он не может соответствовать второму ^NULL^, но только NULL^, поэтому он не работает.

Вы можете сделать это таким образом:

sed ":a s/\^NULL^/^fred^/;ta"

Почему?Потому что это не заменит первое ^NULL^, то перезапуск замены снова и снова, пока не более подмена происходит и потому, что это новый цикл замещения, каждый символ может быть подобран

$ cat temp 

a^NULL^b^c^ 
e^NULL^NULL^NULL^NULL^NULL^NULL^NULL^NULL^NULL^f^ 
g^h^i^NULL^ 

$ cat temp | sed ":a s/\^NULL^/^fred^/;ta" 

a^fred^b^c^ 
e^fred^fred^fred^fred^fred^fred^fred^fred^fred^f^ 
g^h^i^fred^ 

это нормально.

(много хороших ресурсов: http://sed.sourceforge.net/grabbag/tutorials/)

2
There are two different scenarios:- 

1) In First sed command it is like that 
sed "s/\^NULL\^/\^fred\^/g" 

Когда он приходит ко второй линии. Он ищет две строки, поскольку первая - это^NULL ^, а вторая - NULL ^. поэтому здесь он не имеет себе равных. и из-за этого он не заменяет того же. Например, как СЭД ищет слово поиска слова Заменить слово найденного^Null^^^Фред Не найден Null^

2) In second sed command it is like that sed "s/NULL\^/fred\^/g" 

здесь только поиск слово Null^и замену с Фредом ^. Таким образом, это правильно соответствует слову.

Смежные вопросы