zsh: полный относительный путь как абсолютный?

Расстояние Левенштейна является полезной метрикой, дающей представление о количестве различий между двумя строками. Он измеряет количество вставок, удалений и замен, необходимых для перехода от одной строки к другой.

Например, если вы сравните abcdefи bcdef, все символы различны, если вы сравните их один к одному, но только одно удаление нужно, чтобы перейти от одного к другому.

Таким образом, вы можете сделать свой процент как :расстояние / макс. _длина:

perl -MList::Util=max -MText::LevenshteinXS -le '
  ($x, $y) = @ARGV
  print 100 * distance($x, $y) / max(length $x, length $x)
  ' -- "$string1" "$string2"

Или вawk:

awk '
    function min(x, y) {
      return x < y ? x : y
    }
    function max(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 100 * lev(ARGV[1], ARGV[2]) / max(length(ARGV[1]), length(ARGV[2]))
      exit
    }' "$string1" "$string2"

Это дало бы 100 для aпротив bили bc, но 50 для abпротив acили aили bили abcd. Остерегайтесь, вы получите ошибку деления -на -ноль, если попытаетесь сравнить пустую строку с самой собой.

Они ограничены максимальной длиной аргумента команды (128 КБ в современных системах Linux ), хотя это можно обойти, получив строки другим способом (, например, прочитав их из файла ). ] если нужно.

Другой метрикой, которую вы, возможно, захотите рассмотреть, является модуль Дамерау -расстояния Левенштейна(Text::Levenshtein::Damerauвperl). Это то же самое, что и расстояние Левенштейна, за исключением того, что перестановка смежных символов (как в abпротивba)считается как 1 вместо 2.

Это расстояние используется, например, при zshприблизительном сопоставлении (как в [[ abcd = (#a2)acbe ]]для проверки того, что abcdсовпадает с acbeв пределах максимального расстояния 2 )и является общим, когда оно приходит к рассмотрению человеческих опечаток или мутаций ДНК.

1
25.09.2019, 20:06
1 ответ

Следующая функция добавляет $PWD/к любому относительному пути, прежде чем передать его в _files, что является обычной функцией завершения для файлов.

_absolute_files () {
  local expansion=$PREFIX$SUFFIX; expansion=${(e)expansion}
  if [[ "${expansion%%/#}" != "${expansion:a}" ]]; then
    PREFIX="\$PWD/$PREFIX"
  fi
  _files "$@";
}

Это работает во многих распространенных случаях, включая распознавание путей, начинающихся с ~/и таких как абсолютные, а также путей, выраженных с помощью переменной. Я не думал обо всех возможных взаимодействиях с расширением (, например. подстановочных знаков )и с встраиванием.

2
28.04.2021, 23:29

Теги

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