Дополнение с 'sed'

Я пытаюсь выполнить математическую операцию с sed , но она продолжает обрабатывать мои переменные как строки. Ввод такого типа:

 $ echo 12 | sed 's/[0-9]*/&+3/' $ 12+3 

Я хотел бы иметь 15 в качестве вывода. Мне нужно выполнить операцию и заменить ее математический результат только в одном проходе, потому что я запускаю программу как демон Python, и я хочу избежать таких проходов, как перенаправление stdout на файлы, открытие этих файлов, выполнение операций, извлечение результата, сделайте замену. Для меня sed кажется лучше всего выполнять все в одной строке.

Я пытался использовать как входные, так и выходные данные различными способами, например

 $ echo 12 | sed 's/[0-9]*/int(&+3)/' $ echo 12 | sed 's/[0-9]*/\int(&+3)/' $ echo 12 | sed 's/[0-9]*/\int(&+3)/' 

но результат всегда был печатью второго поля.

69 Solutions collect form web for “Дополнение с 'sed'”

Если вы честно хотите использовать sed, то это путь:

 s/[0-9]/<&/g s/0//g; s/1/|/g; s/2/||/g; s/3/

/g; s/4/

|/g; s/5/

||/g; s/6/

/g s/7/

|/g; s/8/

||/g; s/9/

/g : tens s/|</<

|/g t tens s/<//g s/+//g : minus s/|-|/-/g t minus s/-$// : back s/

|/</g s/<\([0-9]*\)$/<0\1/ s/

/9/; s/

||/8/; s/

|/7/; s/

/6/; s/

||/5/; s/

|/4/ s/

/3/; s/||/2/; s/|/1/ s/</|/g t back

Входные данные:

 1+2 100+250 100-250 

Вывод:

 3 350 -150 

Ваша миссия, если вы решите принять ее, заключается в реализации умножения.

sed не самый лучший вариант здесь, он не делает арифметику изначально (см. Increment число, как вы могли бы это сделать, хотя). Вы можете сделать это с помощью awk :

 $ echo 12 | awk '{print $0+3}' 15 

Лучший фрагмент кода, который будет использоваться, будет зависеть от точного формата вашего ввода и того, что вам нужно / нужно делать, если он не является числовым или содержит более одного номера и т. Д.

Вы также можете сделать это только с помощью bash :

 $ echo $(( $(echo 12) + 3 )) 

или используя expr аналогичным образом.

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

 sed 's/[0-9]/<&/g s/0//g; s/1/|/g; s/2/||/g; s/3/

/g; s/4/

|/g; s/5/

||/g; s/6/

/g s/7/

|/g; s/8/

||/g; s/9/

/g : tens s/|</<

|/g t tens s/<//g s/.*\*$/0/ s/^\*.*/0/ s/*|/*/ : mult s/\(|*\)\*|/\1<\1*/ t mult s/*//g s/<//g : back s/

|/</g s/<\([0-9]*\)$/<0\1/ s/

/9/; s/

||/8/; s/

|/7/; s/

/6/; s/

||/5/; s/

|/4/ s/

/3/; s/||/2/; s/|/1/ s/</|/g t back'

Входные данные:

 04*3 4*3 40*3 42*32 150*20 1*3 3*1 0*3 3*0 

Результат: все правильные результаты

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

  echo 'a12' | perl -pe 's/([0-9]+)/($1+3)/e' # the trailing /e means evaluate 

вывод

 a15 

просто подайте строку в калькулятор

  echo 12 | sed 's/[0-9]*/&+3/' | bc 

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

Perl, Ruby, JavaScript и Python – такие языки:

 bash-4.2$ echo 12 | perl -pe 's/\d+/$&+3/e' 15 bash-4.2$ echo 12 | ruby -pe '$_.sub!(/\d+/){|s|s.to_i+3}' 15 bash-4.2$ echo 12 | js -e 'print(readline().replace(/\d+/,function(s){return parseInt(s)+3}))' 15 bash-4.2$ echo 12 | python -c 'import re;print re.sub("\d+",lambda s:str(int(s.group(0))+3),raw_input())' 15 

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

 echo 12 | sed 's/[0-9]*/echo \$(( & + 3 ))/e' 

или

 echo 12 | sed 's/[0-9]*/expr & + 3/e' 

Я думаю, это может потребовать GNU sed, но я не уверен.

Еще одно простое решение bash , которое действительно работает в трубе:

  echo 12 | { read num; echo $(( num + 3)); } 

Если вы смешиваетесь в каком-то башизме:

 echo $(($(echo 12 | sed 's/[0-9]*/&+3/'))) 

Чтобы извлечь номер из текста:

 echo $(($(echo "foo12bar" | sed -r 's/[^0-9]*([0-9]*).*/\1+3/'))) 

Без sed, просто bash:

 var="foo12bar" echo $((${var//[^0-9]/}+3)) 

заменяет каждую незначную цифру ${var//[^0-9]/} и выполняет арифметику в двойных раундах: $((x+3))

  • Sed / awk / perl: изменение частей, сохраняющих текст, и выравнивание по столбцу
  • Как использовать инструменты GNU для извлечения и объединения двух подстрок одной и той же строки?
  • Удалить строки, которые соответствуют точно и только строке
  • Разобрать вывод с динамической шириной столбца и пустыми полями
  • Как удалить файлы и каталоги, которые не находятся в каталоге резервного копирования
  • Как печатать пустые места в первом столбце с помощью awk или sed
  • awk или sed или perl: удалять только символы в определенном месте
  • замените пустое значение на предыдущее значение первого столбца, используя awk и sed
  • Используйте SED или AWK для перемещения строки в новый столбец и строку
  • bash расширяется до того же значения вместо значения строки за строкой в ​​команде sed
  • Удаление ведущих нулей из DATE
  • Interesting Posts

    В OSX ssh-keygen создает ключ, но сеанс не будет подключаться

    Функция сортировки Unix не полностью сортирует строку с числами

    Получение списка пользователей с помощью grepping / etc / passwd

    Как обрабатывать параметр столбца сортировки

    Двойные элементы интерфейса GNOME с Xinerama

    Проблема с конфигурацией Grub2

    cp: не может создать обычный файл: в доступе отказано

    Ошибка разрешения сценария резервного копирования

    Каковы накладные расходы на использование нескольких более мелких устройств рейдов в сравнении с секционированными устройствами рейдов в виде физических томов?

    make ls отображать текущую дату и время

    Можете ли фанатизировать файлы изменений перед доступом к другим приложениям?

    "-bash: /root/.bashrc: Permission denied" при входе в систему

    FreeNX закрывает отображение сразу после успешного подключения в OpenSUSE 12.2

    Openbox, похоже, не имеет правильных переменных окружения

    Совместное использование контента / приложений между консолью и консолью VNC

    Linux и Unix - лучшая ОС в мире.