如何在键之间均匀分配值的总数。
我正在尝试将值均匀分配给键。我不希望值vcn [01-05]和vcn [06-10]分别来到密钥vsn01和vsn02。相反,我想要像vcn [01,03,05,07,09]和vcn [02,04,06,08,10]分别来到密钥vsn01和vsn02。
例如
值的数量: -
vcn01
vcn02
vcn03
vcn04
vcn05
vcn06
vcn07
vcn08
vcn09
vcn10
键
vsn01
vsn02
所需的输出
vsn01
vcn01
vcn03
vcn05
vcn07
vcn09
vsn02
vcn02
vcn04
vcn06
vcn08
vcn10
注意: -
密钥总数 - 20,即vsn [01-20]
总值数 - 100,即vcn [01-100]
尝试: -
#! /bin/bash
function create_vsn_vcn_lists ()
{
pnode_cnt=$1
vcn_cnt=$2
declare -a vcn_lists
for i in `seq $pnode_cnt`; do
${vcn_lists[${i}]}=''
done
for i in `seq $vcn_cnt`; do
for j in `seq $pnode_cnt`; do
ret=`expr ${i} % ${j}`
if [ $ret -eq 0 ]; then
${vcn_lists[${j}]}="${vcn_lists[${j}]} vcn${i}"
fi
done
done
for i in `seq $pnode_cnt`; do
echo ${vcn_lists[${j}]}
done
}
create_vsn_vcn_lists 2 20
答案 0 :(得分:1)
请参阅https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice了解一些的原因,您不应该尝试在shell中操作这样的文本。编写shell的人也为shell编写了awk来调用操作文本,所以只需使用它。
如果您的输入只是您发布的脚本(create_vsn_vcn_lists
)中显示的2个数字:
$ cat tst.awk
BEGIN {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
printf "vsn%02d\n\n", keyNr
for (valNr=keyNr; valNr<=numVals; valNr+=numKeys) {
printf "vcn%02d\n", valNr
}
print ""
}
}
$ awk -v numKeys=2 -v numVals=10 -f tst.awk
vsn01
vcn01
vcn03
vcn05
vcn07
vcn09
vsn02
vcn02
vcn04
vcn06
vcn08
vcn10
或者如果您的输入是2个单独的文件,因为它显示在您发布的示例输入中(number of values
和keys
):
$ cat tst.awk
NR==FNR {
keys[++numKeys] = $0
next
}
{
keyNr = ((FNR-1) % numKeys) + 1
vals[keyNr] = (keyNr in vals ? vals[keyNr] ORS : "") $0
}
END {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
print keys[keyNr] ORS ORS vals[keyNr] ORS
}
}
$ awk -f tst.awk keys values
vsn01
vcn01
vcn03
vcn05
vcn07
vcn09
vsn02
vcn02
vcn04
vcn06
vcn08
vcn10
答案 1 :(得分:0)
您能否请关注awk
并告诉我这是否对您有所帮助。
awk -v count=$(wc -l < keys) 'FNR==NR{a[++i]=$0;next} {b[FNR]=$0} END{for(k=1;k<=count;k++){print b[k] ORS;for(j=k;j<=i;j+=count){print a[j]};print "********"}}' number_of_values keys
此处也添加非单线形式的解决方案。
awk -v count=$(wc -l < keys) '
FNR==NR{
a[++i]=$0;
next}
{
b[FNR]=$0
}
END{
for(k=1;k<=count;k++){
print b[k] ORS;
for(j=k;j<=i;j+=count){
print a[j]};
print "********"}
}
' number_of_values keys
说明: 此处也为代码添加说明。
awk -v count=$(wc -l < keys) ' ##Creating a variable named count whose value is the number of lines in Input_file named keys.
FNR==NR{ ##Checking condition here if FNR==NR which will be TRUE when first Input_file is being read.
a[++i]=$0; ##Creating an array named a whose index is variable i whose value is getting incremented each time with 1 and value is current line.
next} ##next keyword will skip all further statements from here on wards, since we do not want to execute them now.
{
b[FNR]=$0 ##This statement will be executed when 2nd Input_file named keys is being read. Creating array named b whose value is $0 with index FNR.
}
END{ ##Starting END section of awk here now.
for(k=1;k<=count;k++){ ##Starting a for loop whose value starts from k=1 to till value of variable count.
print b[k] ORS; ##Printing the value of array b whose index is k and ORS whose default value is new line.
for(j=k;j<=i;j+=count){ ##Starting a for loop here which starts from j=k to till value of variable i and increment happens with count variable increment.
print a[j]}; ##Printing value of array a whose index is variable j.
print "********"} ##Printing ******** here to segregate between different output sets.
}
' number_of_values keys ##Mentioning the Input_file names here.
答案 2 :(得分:0)
这个怎么样?
#!/bin/bash
function create_vsn_vcn_lists {
local vsn_cnt=$1 vcn_cnt=$2 start=1 i j
for ((i=1; i<=vsn_cnt; ++i, ++start)); do
printf "vsn%02d\n\n" $i
for ((j=start; j<=vcn_cnt; j+=vsn_cnt)); do
printf "vcn%02d\n" $j
done
echo
done
}
create_vsn_vcn_lists 3 10
输出:
vsn01
vcn01
vcn04
vcn07
vcn10
vsn02
vcn02
vcn05
vcn08
vsn03
vcn03
vcn06
vcn09