Дополнение с '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
  • Вырезание текста между двумя запятыми, исключая последующий текст
  • Объединение нескольких файлов с общим заголовком
  • Распечатайте все подходящие строки и предыдущую незакрепленную строку
  • linux & solaris - отдельная сетевая маска IP от обычных IP-адресов
  • Как следить и искать в файле, проходящем через фильтр, менее
  • Как разбить файл на основе информации в столбце в Linux
  • замена sed не будет работать (регулярное выражение)
  • Стратегия для извлечения имени фильма из этого неравномерного набора данных?
  • Awk и отбрасывание несовпадающих токенов в строке?
  • Команды / скрипт Bash для удаления строки из CSV с дубликатом в столбце
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.