我有一个具有如下值的变量
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
根据逗号将变量分成几部分。第二行,从内到外工作:
- 输出第一个值(例如“dog”)、等号,然后输出第二个值,
1
输出以, 等号为后缀的第一个值,然后输出第二个值,- 输出第一个值,后缀为
2
, 等号,然后是第三个值, 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
。如果需要,您可以通过从脚本中的print
和printf
语句中输出适当的引用来修复此问题perl
。和/或定义$newline
为 bash 数组而不是字符串。留给读者作为练习,因为我已经展示了这里使用的足够的原理/技术。
如果您希望将它们声明为导出变量,请使用:
declare -x $newline
请参阅help declare
了解更多详细信息。
顺便说一句,在 中ksh
,您可以使用typeset
代替declare
。 typeset
也受支持bash
但被认为已过时(请参阅help typeset
)bash
。
最后:您确定您不喜欢使用 shell 数组变量(例如dog[0]=/path1,/path2
、dog[1]=/path1
和dog[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