操作系统: kernel 2.6.x
外壳: POSIX兼容外壳
实用工具: BusyBox 1.25
问题:如何从$ VAR1中删除$ VAR2中的值,并将余数输出到$ VAR3?变量中的每个值均以空格分隔。
逻辑:
VAR1="1 2 3 4 5"
VAR2="1 3 5"
for i in $VAR1
if $i is not found in $VAR2; do
append $i to $VAR3
remove trailing space character
done
所需的输出:
VAR3="2 4"
VAR3=$(printf "%d\n" $VAR1 $VAR2 | sort | uniq -u | tr '\n' ' ' | sed 's/\s$//)
$ echo "$VAR3"
2 4
主要缺陷是:它仅保留VAR1
变量中的唯一值。也就是说,如果$VAR1
一个值重复几次,则该值不会出现在中$VAR3
,因为它不是唯一的。
例子:
VAR1="1 2 2 3 4 4 4 5"
VAR2="1 3 5"
# the resulting VAR3 variable is empty
VAR3 = "" # because it is containing only unique values and `2` and `4` repeated few times in the `VAR1`, therefore, they are not unique.
# The right result should be
VAR3 = "2 2 4 4 4"
VAR3=$(printf "%s\n" $VAR2 | awk -v var1="$VAR1" '
{arr2[$1] = 1;}
END {
size = split(var1, arr1);
for(i = 1; i <= size; i++) {
if(!arr2[arr1[i]])
printf "%s ", arr1[i];
}
}' | sed 's/\s$//')
解释
printf "%s\n" $VAR2
-将转换$VAR2
为列-每行一个值。awk ...
-$VAR2
从中删除值$VAR1
。
{arr2[$1] = 1;}
-将所有VAR2
值(它们awk
通过传递给printf
)放入数组,其中值成为数组的索引。在= 1
仅仅意味着真实-这个存在的价值。此技巧为我们提供了下一个行为:第一个值出现创建数组元素,然后,如果再次出现相同的值,它将转到相同的数组索引,换句话说,当相同的值出现几次时,该项不会更改。 。因此,最后,我们将获得该VAR2
变量的所有唯一值。如果为VAR2="one three five"
,则为arr2
:arr2[one] = 1, arr2[three] = 1, arr2[five] = 1
。END { size = split(var1, arr1);
-输入行结束时(VAR2
处理完成),我们将拆分VAR1
为数组-每个值都进入单独的项目。如果为VAR1="one two three four five"
,那么我们将获得follow数组:arr1[1] = one, arr1[2] = two, arr1[3] = three ...
,依此类推。该split
函数返回新创建的数组的大小。if(!arr2[arr1[i]]) printf "%s ", arr1[i];
-然后,遍历所有arr1
项目并进行检查,确实arr2
有该项目的索引。例如:i = 1; arr1[1] = "one"
那么arr2[arr1[i]]
是- arr2[one]
。该项目存在,请勿打印。i = 2; arr1[2] = "two"
。那个arr2[two]
不存在,所以打印出来。因此,我们将打印中的所有值arr1
,而不会出现在中arr2
。sed 's/\s$//'
-删除尾随空间。
与第一个变体相比,这种方式的优点:
# It can process strings
VAR1="one two three four five"
VAR2="one three five"
# the resulting VAR3 variable
VAR3 = "two four"
# It doesn't remove multiple occurrence of one value in the VAR1
VAR1="1 2 2 3 4 4 4 5"
VAR2="1 3 5"
# the resulting VAR3 variable
VAR3 = "2 2 4 4 4"
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句