2015-10-10 4 views
1

У меня есть файл, содержащий много текста и некоторые цифры, описывающие номера < 1 с тремя цифрами точности. Я бы хотел заменить эти цифры примерно эквивалентными целыми процентами (цифры 0-99).заменить шаблон с помощью sed

0.734 -> 73 
0.063 -> 6 
0.979 -> 97 

Было бы здорово округлить правильно, но не обязательно.

Я попытался следующие, и несколько вариантов, и я не могу показаться, чтобы получить еще один матч:

sed -e 's/0\.(\d\d)/&/' myfile.txt 

Что я понимаю в виду, соответствует цифре 0, то десятичная, захватить следующий на цифры и заставить sed заменить весь матч на захваченную часть?

Даже если у меня это получилось, я не знаю, как обращаться с корпусом 0.063 -> 6. Несомненно, это будет полезно для этого.

+1

Я бы использовал awk, python или ruby ​​или любой другой язык сценариев. Формирование + округление чисел не будет проблемой с их использованием. – AlexN

ответ

1

sed поддерживает символ класса, но использует более длинное имя POSIX. Цифры: [[:digit:]]. Короче просто написать [0-9].

Попробуйте это:

sed -E 's/0\.([0-9][0-9]).*/\1/;s/^0//' myfile.txt 

Флаг -E говорит, что использовать современные регулярные выражения. Есть на самом деле 2 команды здесь, разделенная ;:

s/0\.([0-9][0-9]).*/\1/: поставить две цифры следующей 0 и точку в захвате группу и заменить всю строку с этой группой захвата.

s/^0//: удалить начальный ноль из строки после вышеизложенного.

+0

Я снимал свои волосы, пытаясь поместить все в одно регулярное выражение ... Полностью забыл, что мы можем использовать много! – texasbruce

+0

Эта вторая команда только что появилась у меня в голове, когда я прочитал страницу руководства –

0

Помимо sed ответа Zoff дал, вы можете использовать AWK для более эффективной реализации (с округлением):

#round down 
awk '{print int($1*100)}' myfile.txt 
#0.979 -> 97 

#round up 
awk '{printf "%.0f\n",$1*100}' myfile.txt 
#0.979 -> 98 

Баш только реализация:

#round down 
while read n; do result=$(bc <<< "$n*100"); echo ${result%%.*}; done < myfile.txt 
#round up 
while read n; do result=$(bc <<< "$n*100"); printf "%.f\n" $result; done < myfile.txt 
0

Это может работать для вас (GNU СЭД):

sed -r 's/0\.(([1-9][0-9])|0([0-9])).*/\2\3/' file 

Это использует чередование и обратные ссылки (BR) для соответствия требованиям красный рисунок. Если первый шаблон совпадает с вторым BR, он вернет это значение, а третий (BR) будет пустым. Аналогично, если второй шаблон в чередовании совпадает с вторым BR, он будет пустым, а третий BR вернет требуемое значение.

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