Compactar compressão

5

Adoro a expansão de chaves (por exemplo, rm file.{0..5} ). Eu acho muito mais fácil de ler do que a versão expandida. Existe uma maneira rápida e fácil de fazer o oposto?

Por exemplo, dada a entrada www.example.com www1.example.com www2.example.com , a saída seria www{,1,2}.example.com .

    
por Styne666 19.03.2014 / 10:00

2 respostas

2

A resposta curta é não, isso não é possível, mas parece estar relacionado ao maior problema de substring comum que você pode olhe como ponto de partida se você estiver interessado em codificar isso sozinho.

    
por 19.03.2014 / 10:11
2

Encontrar uma expressão bonita em geral é um problema difícil e mal definido (o que significa bela aparência?). Se você está apenas procurando por uma expressão de chave única, ou seja, você tem um monte de strings e deseja expressá-las no formato PREFIX{MIDDLE1,MIDDLE2,...,MIDDLEn}SUFFIX com PREFIXO máximo e SUFFIX, então o problema é bem definido e existe um algoritmo simples :

  1. Encontre o prefixo comum mais longo.
  2. Encontre o sufixo comum mais longo.
  3. Divida as strings.

Vou reutilizar meu longest_common_prefix função.

longest_common_prefix () {
  prefix=
  ## Truncate the two strings to the minimum of their lengths
  if [[ ${#1} -gt ${#2} ]]; then
    set -- "${1:0:${#2}}" "$2"
  else
    set -- "$1" "${2:0:${#1}}"
  fi
  ## Binary search for the first differing character, accumulating the common prefix
  while [[ ${#1} -gt 1 ]]; do
    n=$(((${#1}+1)/2))
    if [[ ${1:0:$n} == ${2:0:$n} ]]; then
      prefix=$prefix${1:0:$n}
      set -- "${1:$n}" "${2:$n}"
    else
      set -- "${1:0:$n}" "${2:0:$n}"
    fi
  done
  ## Add the one remaining character, if common
  if [[ $1 = $2 ]]; then prefix=$prefix$1; fi
}

Eu uso rev para o sufixo porque não tenho vontade de escrever a pesquisa de sufixo comum correspondente. Eu suponho que as strings não contêm nenhuma nova linha.

first=$1; shift
prefix=$(rev <<<"$first")
for x; do
  longest_common_prefix "$prefix" "$(rev <<<"$x")"
done
suffix=$(rev <<<"$prefix")
first=${first%"$suffix"}
prefix=$first
for x; do
  longest_common_prefix "$prefix" "${x%"$suffix"}"
done
printf '%s{%s' "$prefix" "${first#"$prefix"}"
for x; do
  x=${x%"$suffix"}
  printf ',%s' "${x#"$prefix"}"
done

Observe que, se as strings puderem conter os caracteres ,{} , você precisará descobrir alguma forma de citar.

    
por 20.03.2014 / 03:14