2015-09-24 4 views
2

Я пытаюсь заменить серию символов звездочки в текстовом файле -999.9 с помощью sed. Однако я не могу понять, как правильно избежать символа подстановки.Sed заменяет символы звездочки

например.

$ echo "2006.0,1.0,************,-5.0" | sed 's/************/-999.9/g' 
sed: 1: "s/************/-999.9/g": RE error: repetition-operator operand invalid 

Не работает. И

$ echo "2006.0,1.0,************,-5.0" | sed 's/[************]/-999.9/g' 
2006.0,1.0,-999.9-999.9-999.9-999.9-999.9-999.9-999.9-999.9-999.9-999.9-999.9-999.9,-5.0 

ставит -999,9 для каждого *, что не то, что я намеревался.

Спасибо!

ответ

1

* является символом регулярного выражения, который должен быть экранирован.

Вы можете даже использовать BASH замену строки:

s="2006.0,1.0,************,-5.0" 
echo "${s/\**,/-999.9,}" 
2006.0,1.0,-999.9,-5.0 

Использование sed:

sed 's/\*\+/999.9/g' <<< "$s" 
2006.0,1.0,999.9,-5.0 
+0

Я удивлен, что первая команда не вводит тонну '-999.9' 'с' \ ** 'означает ** ноль ** или более вхождения' * '. Выход 'echo '2006.0,1.0, ************, - 5.0" | sed 's/\ **/999.9/g'' is '999.92999.90999.90999.96999.9.999.90999.9,999.91999.9.999.90999.9,999.9,999.9-999.95999.9.999.90999.9' Я ожидал, что вам понадобится' \ * \ ** 'для ** одного ** или более, например' \ * + ', в оболочке так же, как вы делаете в sed и других инструментах, но ясно, что вы этого не делаете и idk почему! –

+1

На самом деле '\ **' даже не является регулярным выражением, это шаблон glob, соответствующий буквенному '*', за которым следует что-то, и поэтому у меня есть ',' в конце концов, чтобы остановить это. – anubhava

+2

Ах, гвоздя, конечно. Еще одна подсказка, что оболочка не предназначена для манипулирования текстами, так как даже те вещи, которые они используют, LOOKS, например, для обработки текста, на самом деле являются чем-то совершенно другим, что имеет смысл для генерации имени файла вместо этого!Может быть, изменить первое предложение из символа '* является символом регулярного выражения' на' *, является символом подстановки, означающим повторение, которое используется в оболочке для globbing и в инструментах UNIX, таких как sed, grep, awk для регулярных выражений', а затем укажите, что находится в вашем 2 скрипта? –

1

Я., * специальные мета-символ, который повторяет предыдущий маркер ноль или более раз. Escape * для того, чтобы соответствовать буквам * символов.

sed 's/\*\*\*\*\*\*\*\*\*\*\*\*/-999.9/g' 
4

Используйте это:

echo "2006.0,1.0,************,-5.0" | sed 's/[*]\+/-999.9/g' 

Тест:

$ echo "2006.0,1.0,************,-5.0" | sed 's/[*]\+/-999.9/g' 
2006.0,1.0,-999.9,-5.0 
4

Любой из них (и более) является регулярное выражение, которое будет изменять эту строку, как вы хотите:

$ echo "2006.0,1.0,************,-5.0" | sed 's/\*\**/999.9/g' 
2006.0,1.0,999.9,-5.0 

$ echo "2006.0,1.0,************,-5.0" | sed 's/\*\+/999.9/g' 
2006.0,1.0,999.9,-5.0 

$ echo "2006.0,1.0,************,-5.0" | sed -r 's/\*+/999.9/g' 
2006.0,1.0,999.9,-5.0 

$ echo "2006.0,1.0,************,-5.0" | sed 's/\*\{12\}/999.9/g' 
2006.0,1.0,999.9,-5.0 

$ echo "2006.0,1.0,************,-5.0" | sed -r 's/\*{12}/999.9/g' 
2006.0,1.0,999.9,-5.0 

$ echo "2006.0,1.0,************,-5.0" | sed 's/\*\{1,\}/999.9/g' 
2006.0,1.0,999.9,-5.0 

$ echo "2006.0,1.0,************,-5.0" | sed -r 's/\*{1,}/999.9/g' 
2006.0,1.0,999.9,-5.0 

sed работает на регулярных выражениях, а не на строках, поэтому вам нужно изучить синтаксис регулярных выражений, если вы собираетесь использовать sed и, в частности, разницу между BRE (который используется sed по умолчанию) и ERE (которые некоторые сады могут быть переданы вместо этого) и PCRE (которые sed никогда не использует, а некоторые другие инструменты и «регулярные проверки»). Только первое решение выше - BRE, который будет работать на всех seds на всех платформах. Google - ваш друг.

0

Когда эта возможность была введена в gawk, я понятия не имею!

gawk -F, '{sub(/************/,"-999.9",$3)}1' OFS=, file 
2006.0,1.0,-999.9,-5.0 
Смежные вопросы