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

Если программное обеспечение моделирования действительно проверяет, что число дисплея 0, можно принять меры, чтобы удаленный дисплей был 0. Удостоверьтесь, что Вы не работаете Xsun локально или выполненный это на другом дисплее (например. Xsun :1). В конфигурационном файле сервера OpenSSH /etc/ssh/sshd_config, добавьте строку X11DisplayOffset 0.

Если Вы соединяетесь по ssh, DISPLAY переменная среды будет установлена на localhost:0.0 (установив X11DisplayOffset как выше). Это (для всех практических целей) синонимично с localhost:0 который принимает Ваше приложение, таким образом, можно вставить это Ваш .profile:

DISPLAY=${DISPLAY%.0}

Если программное обеспечение моделирования хочет локальный дисплей :0, можно попытаться выполнить его в Xvfb (виртуальный X-сервер кадрового буфера, я не знаю, поставляется ли это с Солярисом). Как выше, не выполняйте X-сервер, локально демонстрирующийся :0, работайте на нем :1 если вообще. С Xvfb Вы не можете соединиться с дисплеем легко, но Вы видите кадры экранов.

Xvfb :1 -screen 0 1024x768x16 -fbdir /tmp &
DISPLAY=:1 simulation-program &
xwud -in /tmp/Xvfb_screen0

С другой стороны, Вы могли бы попробовать X-сервер, который отображается в окне, таком как Xnest, Xephyr или VNC — снова, если Вы выполняете локальный X-сервер вообще на машине Sun, выполните его демонстрирующийся :1. Например, с VNC:

vncserver :1

и можно даже соединиться с тем сервером со средством просмотра VNC на машине Windows.

40
21.04.2012, 15:05
11 ответов

Если Вы честно хотите использовать 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

Ваша миссия, должен Вы принимать решение принять его, должен реализовать умножение.

83
27.01.2020, 19:35
  • 1
    +1 для проблемы, любите его! Возможно, это было бы чем-то для Гольфа Кода;-p –  Tatjana Heuser 20.04.2012, 17:15
  • 2
    И некоторые люди говорят, что программирование не является математикой. Этот небольшой драгоценный камень опровергает их всех. Лучшее использование Основы 1 когда-либо. –  Bruce Ediger 20.04.2012, 18:42
  • 3
    Хороший! - @Simon: Я бросаю вызов Вам реализовывать tetration :P –  A T 20.04.2012, 20:45
  • 4
    +1 Это - красивый пример того, что может породить неправильное представление, соединенное с креативностью. –  rozcietrzewiacz 20.04.2012, 22:28
  • 5
    быть сделанным с sed - и это масштабируется к огромным числам вполне хорошо, также! –  Toby Speight 13.04.2016, 23:07

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

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

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

Вы могли также сделать это только с bash:

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

или использование expr подобным способом.

20
27.01.2020, 19:35

Я пытался принять Ваш вызов @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

Вывод: все корректные результаты

17
27.01.2020, 19:35

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

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

вывод

a15
12
27.01.2020, 19:35
  • 1
    может также сделать это без круглых скобок получения: perl -pe 's/[0-9]+/$&+3/e' –  glenn jackman 20.04.2012, 16:12

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

 echo 12 | sed 's/[0-9]*/&+3/' | bc
8
27.01.2020, 19:35
  • 1
    это не будет работать, если будет текст среди чисел. –  glenn jackman 21.04.2012, 15:25

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

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
5
27.01.2020, 19:35

Другой простой bash решение, которое на самом деле работает в канале:

 echo 12 | { read num; echo $(( num + 3)); }
1
27.01.2020, 19:35

Если Вы смешиваетесь в некотором bashism:

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

Извлечь число из текста:

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

Без sed просто колотите:

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

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

1
27.01.2020, 19:35
  • 1
    Там нет никакого bashism. $((...)) был представляют POSIX (bashism $[...]). ${var//xxx/x} kshism, также скопированный zsh и ударом. sed -r GNUism –  Stéphane Chazelas 19.09.2012, 01:06

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

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

или

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

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

6
27.01.2020, 19:35
  • 1
    Это - расширение гну. сообщение –  Kevin 30.03.2013, 19:02
  • 2
    Хорошо Вы правы, но ответ идет вне, он реализует общее дополнение не конкретное, можно подать любые два числа, и Вы получите –  Luigi Tiburzi 01.04.2013, 21:56
  • 3
    @LuigiTiburzi Его довольно простое для обобщения этого к входу стиля "x+y": echo 12+3 | sed -r 's/([0-9]*) *\+ *([0-9]*)/expr \1 + \2/e' –  Digital Trauma 15.10.2014, 21:28

Хотя использование выражения sed — это здорово, оно имеет свои ограничения. Например, следующая ошибка:

$ echo "1000000000000000000000000000000+1" | sed -e 's/\([0-9]*\)+\([0-9]*\)/expr \1 + \2/e'
expr: 1000000000000000000000000000000: Numerical result out of range

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

#!/bin/sed -f

s/+/\n/g
s/$/\n\n0/

:LOOP
s/^\(.*\)\(.\)\n\(.*\)\(.\)\n\(.*\)\n\(.\)$/0\1\n0\3\n\5\n\6\2\4/
h
s/^.*\n.*\n.*\n\(...\)$/\1/

# decimal full adder module
# INPUT:  3digits (Carry in, A, B,)
# OUTPUT: 2bits (Carry, Sum)
s/$/;000=00001=01002=02003=03004=04005=05006=06007=07008=08009=09010=01011=02012=03013=04014=05015=06016=07017=08018=09019=10020=02021=03022=04023=05024=06025=07026=08027=09028=10029=11030=03031=04032=05033=06034=07035=08036=09037=10038=11039=12040=04041=05042=06043=07044=08045=09046=10047=11048=12049=13050=05051=06052=07053=08054=09055=10056=11057=12058=13059=14060=06061=07062=08063=09064=10065=11066=12067=13068=14069=15070=07071=08072=09073=10074=11075=12076=13077=14078=15079=16080=08081=09082=10083=11084=12085=13086=14087=15088=16089=17090=09091=10092=11093=12094=13095=14096=15097=16098=17099=18100=01101=02102=03103=04104=05105=06106=07107=08108=09109=10110=02111=03112=04113=05114=06115=07116=08117=09118=10119=11120=03121=04122=05123=06124=07125=08126=09127=10128=11129=12130=04131=05132=06133=07134=08135=09136=10137=11138=12139=13140=05141=06142=07143=08144=09145=10146=11147=12148=13149=14150=06151=07152=08153=09154=10155=11156=12157=13158=14159=15160=07161=08162=09163=10164=11165=12166=13167=14168=15169=16170=08171=09172=10173=11174=12175=13176=14177=15178=16179=17180=09181=10182=11183=12184=13185=14186=15187=16188=17189=18190=10191=11192=12193=13194=14195=15196=16197=17198=18199=19/
s/^\(...\)[^;]*;[^;]*\1=\(..\).*/\2/
H
g
s/^\(.*\)\n\(.*\)\n\(.*\)\n...\n\(.\)\(.\)$/\1\n\2\n\5\3\n\4/
/^\([0]*\)\n\([0]*\)\n/ {
        s/^.*\n.*\n\(.*\)\n\(.\)/\2\1/
        s/^0\(.*\)/\1/
        q
}
b LOOP

Это работает путем реализации модуля десятичного сумматора, который складывает две входные цифры (A и B ), а также бит переноса и производит бит суммы и переноса. Идея заимствована из электронной, где двоичный сумматор делает то же самое для двоичных чисел. Все, что нам нужно сделать, это зациклить сумматор на всех цифрах, и мы можем складывать числа произвольной длины (, ограниченные памятью ). Ниже показан сумматор в действии:

./decAdder.sed
666666666666666666666666666666999999999999991111111112222+1100000000000000000000011111111111111111111111111111111111
1766666666666666666666677777778111111111111102222222223333

Точно так же можно реализовать двоичный (или любой другой базовый )сумматор. Все, что вам нужно сделать, это заменить строку, начинающуюся с s/$/;000=00001..., на правильный шаблон замены для данного основания. Например:s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/является шаблоном замены для двоичного сумматора произвольной длины.

Вы можете разместить код, задокументированный на моем github .

0
27.01.2020, 19:35

Вот Perl-решение:

echo 12 | perl -wlpe '$_ += 3'
# Output:  15

Если вы предпочитаете изменить первый набор цифр в строке, вы можете использовать:

echo I am 12 years old. | perl -wlpe 's/(\d+)/$1 + 3/e'
# Output:  I am 15 years old.

Если вы предпочитаете изменять все наборы цифр в строке, вы можете использовать модификатор /g, например:

echo They are 11, 12, and 13 years old. | perl -wlpe 's/(\d+)/$1 + 3/eg'
# Output:  They are 14, 15, and 16 years old.
0
27.01.2020, 19:35

Теги

Похожие вопросы