将两个 find 命令输出附加到单个变量,但不附加到文件

将两个 find 命令输出附加到单个变量,但不附加到文件

我的用例是将两个 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=barfoo=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无关,并且并没有真正做zshmapfile映射) 是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 进行分割。在这种情况下,退出状态是直接可用的($?像往常一样)。

要将元素追加到数组中,在 和 中zshbash您可以执行以下操作:

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是元素的数量以及最后分配的索引。

相关内容