![将两个 find 命令输出附加到单个变量,但不附加到文件](https://linux22.com/image/203012/%E5%B0%86%E4%B8%A4%E4%B8%AA%20find%20%E5%91%BD%E4%BB%A4%E8%BE%93%E5%87%BA%E9%99%84%E5%8A%A0%E5%88%B0%E5%8D%95%E4%B8%AA%E5%8F%98%E9%87%8F%EF%BC%8C%E4%BD%86%E4%B8%8D%E9%99%84%E5%8A%A0%E5%88%B0%E6%96%87%E4%BB%B6.png)
我的用例是将两个 find 命令输出到单个变量(而不是文件),我尝试过并了解到它不起作用的一些事情是
实际的find
命令是:
find /opt/apps -xdev -type f -name '*vunn*-2*jar'
find /opt/apps -xdev -type f -name '*robj-2*jar'
选项1:仅保存第二个输出。
temp_jars=$(find /opt/apps -xdev -type f -name '*vunn*-2*jar')
temp_jars=$(find /opt/apps -xdev -type f -name '*robj*-2*jar')
选项2:基于参考,在下面尝试过,但只有第一个命令被执行。
export temp_jars="$(find /opt/apps -xdev -type f -name '*vunn*-2*jar' && find /opt/apps -xdev -type f -name '*robj-2*jar')"
感谢您的帮助。
答案1
有多种方法可以做到这一点。对于您的情况,最简单的方法是组合命令find
并避免整个问题:
temp_jars=$(find /opt/apps -xdev -type f \( -name '*vunn*-2*jar' -o -name '*robj-2*jar' \)
对于其他情况,您确实需要多个命令,您可以单独运行它们,然后附加输出到变量而不是覆盖(这是您运行然后执行的操作foo=bar
,foo=baz
只保留最后一个操作,因为它覆盖了第一个操作):
$ var=$(echo foo)
$ var="$var $(echo bar)"
$ echo "$var"
foo bar
或者,一步完成:
$ var="$(echo foo; echo bar)"
$ echo "$var"
foo
bar
您使用的方法(&&
而不是)意味着;
仅当第一个命令成功时才会执行第二个命令,因此如果您的第一个命令find
由于某种原因失败(请注意,find
如果没有找到结果,则不会失败,只会发生错误,例如,如果您告诉它在不存在的目录中搜索),第二个将不会运行。就您而言,我看不出&&
有任何失败的原因,您确定它不起作用吗?
答案2
要存储多个值,请使用数组,而不是标量变量:
readarray -td '' temp_jars < <(
find /opt/apps -xdev -type f -name '*vunn*-2*jar' -print0
find /opt/apps -xdev -type f -name '*robj*-2*jar' -print0
)
(-d
此处用于指定 NUL 作为分隔符的选项需要 bash 4.4 或更高版本)。
不过在这里,除非重要的是,vunn
将这些列在这些之前robj
,正如 @terdon 已经说过的,否则您可以使用一个find
命令来完成此操作。
然后,要将文件名作为单独的参数传递给某些命令,请使用"${temp_jars[@]}"
.
例如:
printf ' * %s\n' "${temp_jars[@]}"
请注意,您不能使用export
数组变量。环境变量只是标量,就像 bash 变量不能包含 NUL 字节,因此不能可靠地保存文件路径列表(它们本身也可以由任何(非空)非空字节序列组成),除非您使用某种形式的编码/引用。
另请注意,由进程替换启动的子 shell 的退出状态(在本例中将是第二个find
命令的退出状态)会丢失,但在最新版本中,bash
您可以使用wait "$!"; status=$?
.
readarray
(又名,虽然它与'smapfile
无关,并且并没有真正做zsh
mapfile
映射) 是bash
特定的。这里的等价物zsh
是:
temp_jars=(
${(0)"$(
find /opt/apps -xdev -type f -name '*vunn*-2*jar' -print0
find /opt/apps -xdev -type f -name '*robj*-2*jar' -print0
)"}
)
使用0
参数扩展标志对 NUL 进行分割。在这种情况下,退出状态是直接可用的($?
像往常一样)。
要将元素追加到数组中,在 和 中zsh
,bash
您可以执行以下操作:
temp_jars+=(more elements)
使用 bash,readarray
您可以使用该-O
选项来指定从数组的哪个索引开始存储值。
您可以使用以下方法获取数组的最后分配的索引:
indexes=("${!temp_jars[@]}"); last_index=${indexes[-1]}
然后使用:
readarray -td '' -O "$((last_index + 1))" temp_jars < <(find ... -print0)
如果数组最初并不稀疏(就像之前的 Straight 后的情况一样readarray
),则可以简化为:
readarray -td '' -O "${#temp_jars[@]}" temp_jars < <(find ... -print0)
其中${#temp_jars[@]}
是数组中元素的数量(如果数组不是稀疏的,则对应于 1 加最后分配的索引,因为数组索引从 0 而不是 1 开始)。
在 中zsh
,与大多数其他 shell 一样,数组不是稀疏的,并且索引从 1 开始;$#temp_jars
是元素的数量以及最后分配的索引。