проблема сценария оболочки с использованием операторов

Я выполняю Crunchbang 10 на 10-дюймовом нетбуке с ЦП AMD C60. Crunchbang довольно легок: На Нетбуке ограничения будут главным образом на аппаратной стороне.

Пример: Работая над командной строкой или в простом текстовом редакторе, ЦП работает приблизительно в 5%. Запись живого аудиопотока через Интернет или использование браузера как Firefox будут приносить ЦП до 50-60%.

Поскольку это является самым близким к Debian, который я могу выполнить правильно в данный момент [у меня действительно нет знания для устранения проблем теперь], я очень очень доволен им.

Существует достаточно flamewars, о которых GUI использовать – и я не забочусь очень: Я сделал опыт, что KDE и GNOME немного тяжелы для Нетбука. Мне действительно понравилось использовать Монетный двор Выпуск Debian с выполнением XFCE, от того, где я переключился на даже – по крайней мере, это чувствовало так – легче Рабочий стол LXDE. Каждый Рабочий стол является другим подходом для получения сделанного материала. В основном: Пицца или Паста? независимо от того, что каждый предпочитает в данный момент. Но, как упомянуто выше: KDE немного тяжел для Нетбука. Я уверен, что существует тысяча способов зафиксировать это, но я действительно люблю минимализм OpenBox, поскольку он реализован в Crunchbang.

И затем существует также https://en.wikipedia.org/wiki/Lightweight_Linux_distribution, чтобы дать одному хороший первый обзор.

4
18.02.2014, 03:25
3 ответа

Вы не должны использовать expr в этом случае, попробуйте следующее:

table_value=$(( 1 / (1+$levenshtein_return) ))
4
27.01.2020, 20:52
[115352]Хотя это не документировано и не гарантировано POSIX, кажется, что из-за того, что POSIX требует, чтобы оболочки обрабатывали C-константы и многие из тех же операторов, что и C, они, похоже, исходят и от всех остальных простых C-целых математических операторов, включая троичные тесты и присваивания:

Я только что протестировал вышеприведённый базовый пример в zsh, bash, bash's sh и dash. Все ведут себя корректно и одинаково.[115355]

1
27.01.2020, 20:52

Там есть несколько проблем.

В:

table_value=$( expr( 1/ ( 1 + $levenshtein_return ) ) )

Символы ( и ) являются специальными для оболочки, поэтому должны быть экранированы. И вы хотите выполнить именно команду expr, а не expr(. Также вы должны передавать операторы и операнды как отдельные аргументы в expr.

table_value=$(expr '(' 1 / "(" 1 + "$levenshtein_return" \) ')' )

(выше показаны различные способы цитирования символов ( и )).

Теперь, как показал @Gnouc, expr больше не нужен для арифметической оценки, поскольку все современные оболочки POSIX имеют для этого встроенный оператор $((...)).

Теперь, за исключением zsh и ksh93, ни expr, ни $((...)) не выполняют арифметику с плавающей точкой. Поэтому в обоих случаях:

table_value=$(expr 1 / "(" 1 + "$levenshtein_return" ")" )

и

table_value=$((1 / (1 + $levenshtein_return)))

значение будет целочисленным, то есть обычно либо 0, либо 1.

Если вы хотели получить 1, если строки одинаковые, и 0, если они разные (но тогда вам не нужно вычислять расстояние, если вы хотите проверить, что две строки одинаковые), то вы бы написали:

table_value=$((!$levenshtein_return))

В ksh93 или zsh, если вам нужно значение с плавающей точкой, вы бы написали:

table_value=$((1. / (1 + $levenshtein_return)))

В других оболочках и в POSIX, если вам нужна арифметика с плавающей точкой, вы обычно вызываете команду, которая может это сделать, например awk, bc или... .. php.

Здесь, поскольку вы уже вызываете php, вы также можете заставить его выполнить окончательный расчет. Если вы используете awk, обратите внимание, что awk также может легко выполнить расчет расстояния Левенштейна:

table_value=$(awk '
    function min(x, y) {
      return x < y ? x : y
    }
    function lev(s,t) {
      m = length(s)
      n = length(t)

      for(i=0;i<=m;i++) d[i,0] = i
      for(j=0;j<=n;j++) d[0,j] = j

      for(i=1;i<=m;i++) {
        for(j=1;j<=n;j++) {
          c = substr(s,i,1) != substr(t,j,1)
          d[i,j] = min(d[i-1,j]+1,min(d[i,j-1]+1,d[i-1,j-1]+c))
        }
      }

      return d[m,n]
    }

    BEGIN {print 1 / (1 +lev(ARGV[1], ARGV[2])); exit}' String1 String2
)
1
27.01.2020, 20:52

Теги

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