如何合并和排序两个 shell 变量,删除重复项

如何合并和排序两个 shell 变量,删除重复项

在我的 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

在上面两个命令中,您可以将echos 替换为生成该输出的其他命令,而无需通过 shell 变量。

但是,如果 shell 变量中确实有列表,您也可以printf同时打印这两个列表,而无需对多个命令进行分组:

printf "%s\n" "$args1" "$args2" | grep -v "^Matching" | sort -u

相关内容