Mapear cadeia de caracteres de var1 para var2 (pesquisa)

0

Eu quero fazer uma pesquisa insensível a maiúsculas e minúsculas em VAR2 com base no conteúdo da VAR1 que contém alguns parâmetros no formato key : value . Se um VAR1 key estiver presente, substitua o valor em VAR2.

Por exemplo, para:

VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom

Eu quero que o resultado seja:

VAR3='viki','albert','rich'

VAR1 pode estar vazio.

    
por Nir 11.06.2018 / 14:49

3 respostas

3

com zsh :

VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom

typeset -A map
for i ("${(@s(,))VAR1}") map[${(L)i%%:*}]=${i#*:}
out=()
for i ("${(@s(,))VAR2}") out+=${(qq)${map[${(L)i}]:-$i}}
VAR3=${(j(,))out}

printf '%s\n' "$VAR3"

Saída:

'viki','albert','rich'

Mesmo com awk (que você pode usar com zsh ou qualquer shell semelhante a Bourne como bash ):

VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom

export VAR1 VAR2
awk -v q=\' 'BEGIN {
  n = split(ENVIRON["VAR1"], a, ",")
  for (i = 1; i <= n; i++) {
    k = v = a[i]
    sub(/:.*/, "", k)
    sub(/[^:]*:/, "", v)
    map[tolower(k)] = v
  }
  n = split(ENVIRON["VAR2"], a, ",")
  for (i = 1; i <= n; i++) {
    k = tolower(a[i])
    out = out sep q (k in map ? map[k] : a[i]) q
    sep = ","
  }
  print out
}'

(uma diferença é que aqui só colocamos os valores dentro de aspas simples. Se o valor contiver aspas simples, como foo'bar , você receberá 'foo'bar' , enquanto zsh ${(qq)var} dará 'foo'\''bar' ).

A versão zsh permite qualquer valor para os itens. Eles podem conter qualquer valor de byte, incluindo newline e NUL, ou um valor vazio. O awk one não suportará NULs, já que elas não podem ser armazenadas em variáveis de ambiente e, dependendo da implementação, podem sufocar itens contendo bytes que não formam caracteres válidos.

Observe que, com ambos, VAR2= é entendido como uma lista vazia, enquanto VAR2=, é entendido como uma lista de dois elementos vazios, não há como expressar uma lista de um elemento vazio.

    
por 11.06.2018 / 15:46
0

Usando awk com base em RS (separador de registro):

VAR3=$(awk '
         BEGIN{RS="[,\n]";FS=":";ORS=","} 
         NR==FNR{a[tolower($1)]=$2}
         NR>FNR{printf "%s7%s7",(FNR>1?ORS:""),(a[$1]?a[$1]:$1)}
       ' <(echo "$VAR1") <(echo "$VAR2") 
      )

A matriz a é preenchida com o conteúdo de VAR1 com o par de chave e valor. Este é usado ao analisar a segunda variável e o valor é substituído se existir uma entrada de array.

    
por 11.06.2018 / 16:12
0

Uma solução bash (4.0+) que cria uma tabela lookup (uma matriz associativa) usando as chaves com menos letras de VAR1 e os valores associados. Em seguida, ele percorre os valores em VAR2 e cria VAR3 com valores da tabela de consulta ou de VAR2 se não houver chave na tabela de consulta correspondente à corrente VAR2 .

VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom

declare -A lookup

# build lookup table
while read -d , key_value; do
    # $key_value is a string like "tom:rich", separate these into key and value:
    IFS=: read key value <<<"$key_value"

    # add lower-cased key to table with value
    lookup[${key,,}]=$value
done <<<"$VAR1,"

# do lookups in table
while read -d , string; do
    # get newstring from table, but use $string if there's no entry:
    newstring=${lookup[${string,,}]:-$string}

    # add $newstring to VAR3, with a delimiting comma unless VAR3 is empty
    VAR3+="${VAR3:+,}'$newstring'"
done <<<"$VAR2,"

printf 'VAR3 = %s\n' "$VAR3"

Este código gera

VAR3 = 'viki','albert','rich'

Isso pressupõe que os valores em VAR1 e VAR2 não contenham novas linhas.

    
por 11.06.2018 / 16:07