从单个变量创建与多个变量分配相对应的文本

从单个变量创建与多个变量分配相对应的文本

我有一个具有如下值的变量

line=dog,/path1,/path2

我想要的是从值创建一个变量; iedog应该是变量并且想要得到以下输出:

dog=/path1,/path2
dog1=/path1
dog2=/path2

同样,如果我有,line=bull,/val1,/val2我需要以下输出

bull=/val1,/val2
bull1=/val1
bull2=/val2

请注意,line只有三个值,以逗号分隔。

答案1

我认为这就是你想要做的事情:

line='dog,/path1,/path2'
IFS=', ' read -r -a dog <<< "$line"

echo "$dog"
dog
echo "${dog[1]}"
/path1
echo "${dog[2]}"
/path2 

这假设您的 shell 是 bash。

答案2

这是一个以 bash 为中心的解决方案:

IFS=, read -r -a vars <<<"$line"
printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"

第一行$line根据逗号将变量分成几部分。第二行,从内到外工作:

  1. 输出第一个值(例如“dog”)、等号,然后输出第二个值,
  2. 1输出以, 等号为后缀的第一个值,然后输出第二个值,
  3. 输出第一个值,后缀为2, 等号,然后是第三个值,
  4. printf这三个字符串,由换行符分隔。

正如您的问题一样,这个答案被硬编码为在 中包含三个值$line

输入和输出示例(前导$是 shell 提示符):

$ line=dog,/path1,/path2
$ IFS=, read -r -a vars <<<"$line"
$ printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"
dog=/path1,/path2
dog1=/path1
dog2=/path2

您可以轻松地将 printf 输出重定向到文件。

答案3

如果您正在使用bash,您可以执行以下操作(使用额外的echo语句来显示每个阶段发生的情况):

$ line=dog,/path1,/path2

$ newline=$(printf "%s\n" "$line" | 
            perl -n -e 'BEGIN {$count=1};
                        my ($var,@values) = split /,/;
                        print "$var=" . join(",",@values);
                        foreach (@values) {
                            printf "%s%i=\"%s\" ",$var, $count++, $_
                        }')

$ echo "$newline"
dog=/path1,/path2 dog1=/path1 dog2=/path2

$ declare $newline

$ declare | grep '^dog'
dog=/path1,/path2
dog1=/path1
dog2=/path2

这用于用逗号perl分隔。$line第一个字段保存在 中$var,其余字段保存在名为 的数组中@values。然后它会生成适合与 bashdeclare命令一起使用来设置变量的输出。

请注意,$newline不是也不应该在该declare行中使用双引号。如果用双引号括起来,declare则只会得到一个参数,而不是三个以空格分隔的参数。

这里缺乏引用的一个令人不快的副作用是declare 将要如果任何字段值包含空格字符等,则会失败。例如line=dog,/path /with / spaces,/path2。如果需要,您可以通过从脚本中的printprintf语句中输出适当的引用来修复此问题perl。和/或定义$newline为 bash 数组而不是字符串。留给读者作为练习,因为我已经展示了这里使用的足够的原理/技术。

如果您希望将它们声明为导出变量,请使用:

declare -x $newline

请参阅help declare了解更多详细信息。

顺便说一句,在 中ksh,您可以使用typeset代替declaretypeset也受支持bash但被认为已过时(请参阅help typesetbash


最后:您确定您不喜欢使用 shell 数组变量(例如dog[0]=/path1,/path2dog[1]=/path1dog[2]=/path2)而不是单独的变量吗?这就是他们存在的目的。

答案4

你可以做这样的事情。我按照你的方式定义了这条线。接下来,我解析该行中的第一个逗号分隔的标记(我假设这里对变量名有效)。然后,我根据第一个标记构造两个新变量,并将它们分配给该行中的第二个和第三个以逗号分隔的标记。

line="dog,/path1,/path2"
first="$(echo "${line}" | awk -F, '{ print $1 }')"
eval "${first}1=$(echo "${line}" | awk -F, '{ print $2 }')"
eval "${first}2=$(echo "${line}" | awk -F, '{ print $3 }')"

echo "${dog1}"
/path1
echo "${dog2}"
/path2

相关内容