将字符串从 var1 映射到 var2(查找)

将字符串从 var1 映射到 var2(查找)

我想VAR2根据 VAR1 的内容进行不区分大小写的查找,其中包含以下形式的一些参数keyvalue。如果VAR1 key存在 a 则替换 VAR2 中的值。

例如:

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

我想要的结果是:

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

VAR1可以为空。

答案1

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"

输出:

'viki','albert','rich'

与 相同awk(您可以与zsh或任何类似 Bourne 的 shell 一起使用,例如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
}'

(一个区别是,这里我们只将值括在单引号内。如果值本身包含单引号,例如foo'bar,则'foo'bar'whilezsh${(qq)var}给出'foo'\''bar')。

zsh版本允许项目的任何值。它们可以包含任何字节值,包括换行符和 NUL 或空值。该awk版本不支持 NUL,因为它们无法存储在环境变量中,并且根据实现的不同,可能会阻塞包含不形成有效字符的字节的项目。

请注意,对于both,VAR2=被理解为一个空列表,而VAR2=,被理解为2个空元素的列表,没有办法表达一个空元素的列表。

答案2

使用awk基于RS(记录分隔符):

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

a数组填充VAR1有键和值对的内容。在解析第二个变量时使用此变量,如果存在数组条目,则值将被替换。

答案3

一个(4.0+) 解决方案,使用小写键和关联值bash构建表(关联数组)。然后,它会遍历查找表中的值并使用查找表中的值进行构建,如果查找表中没有与当前字符串对应的键,则使用查找表中的值进行构建。lookupVAR1VAR2VAR3VAR2VAR2

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"

这段代码输出

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

VAR1这假设和中的值VAR2不包含换行符。

相关内容