![如何合并和排序两个 shell 变量,删除重复项](https://linux22.com/image/206047/%E5%A6%82%E4%BD%95%E5%90%88%E5%B9%B6%E5%92%8C%E6%8E%92%E5%BA%8F%E4%B8%A4%E4%B8%AA%20shell%20%E5%8F%98%E9%87%8F%EF%BC%8C%E5%88%A0%E9%99%A4%E9%87%8D%E5%A4%8D%E9%A1%B9.png)
在我的 bash 脚本中,我将有两个名为“args1”和“args2”的变量。他们每个人都会有这样的内容:
Matching cluster names:
[a-z]+
[a-z]+
...
所以“args1”可能是:
Matching cluster names:
dev1ff
dev2ff
而“args2”可以是:
Matching cluster names:
dev2ff
dev3ff
我需要将这些结合起来产生:
Matching cluster names:
dev1ff
dev2ff
dev3ff
我可以用这一行来接近这一点:
echo "$(echo "$args1" | grep -v "^Matching") $(echo "$args2" | grep -v "^Matching")" | sort -u
这会产生大致如下的结果:
Matching clusters:
dev1ff
dev2ff dev3ff
实际名称并不重要,但问题是我无法在第一个和第二个块之间插入换行符。我在两个“$(...)”块之间的空间中尝试了几种变体,但没有任何效果。
答案1
由于命令替换会删除任何尾随换行符,因此您将获得两个命令替换之间的空格作为它们之间的唯一分隔符。因此结果如下。
对于任何echo
支持的-e
,您可以使用
echo -e "$(...)\n$(...)" | sort -u
在中间添加一个换行符。不过,如果您的数据有反斜杠,那么echo
它们也会被转换。为了避免这种情况,你可以printf
像这样使用:
printf "%s\n" "$(...)" "$(...)" | sort -u
(格式字符串根据需要重复多次,因此使用两个参数时,"%s\n"
其工作方式与 相同%s\n%s\n
。此外,您可能想使用printf
而不是echo
无论如何,请参阅为什么 printf 比 echo 更好?)
但你并不真正需要命令替换;echo "$(something)"
接近于直接运行something
。您可以sort -u
使用花括号将要定向的两个命令分组:
{ echo "$args1" | grep -v "^Matching"; echo "$args2" | grep -v "^Matching"; } | sort -u
或者,注意到两个 grep 都执行相同的操作,将 grep 移到大括号之外:
{ echo "$args1"; echo "$args2"; } | grep -v "^Matching" | sort -u
在上面两个命令中,您可以将echo
s 替换为生成该输出的其他命令,而无需通过 shell 变量。
但是,如果 shell 变量中确实有列表,您也可以printf
同时打印这两个列表,而无需对多个命令进行分组:
printf "%s\n" "$args1" "$args2" | grep -v "^Matching" | sort -u