我如何将“find”的结果传送到我的 bash 脚本?

我如何将“find”的结果传送到我的 bash 脚本?

我正在尝试将命令的结果传输find到 bash 脚本。这是为了简化(或许是自动化)我一直在进行的流程。

这是我想要运行的命令

find . -type f -iname '*.mp4' -exec echo {}|./indexer.sh \;

indexer.sh是 ofc chmod +x,因此它可以执行。

indexer.sh目前包含

#!/bin/zsh
read foo
echo "You entered '$foo'"

如果我运行,$ echo foo | ./indexer.sh我会得到以下输出 You entered 'foo'

但是当我运行时find . -type f -iname '*.mp4' -exec echo {}|./indexer.sh \;收到以下错误消息:

find: -exec: no terminating ";" or "+"
You entered ''

那么我怎样才能将 find 的输出导入到我的脚本中呢?

答案1

我将使用参数而不是读取语句和管道来重写它,

find . -type f -iname '*.mp4' -exec ./indexer.sh {} \;

使用以下 indexer.sh,

#!/bin/zsh

echo "You entered '$1'"

答案2

你的误解是它echo {}|./indexer.sh被视为一个单位。事实并非如此。问题在于你的 shell 将管道解释为它运行find。因此,它正在运行……

find . -type f -iname '*.mp4' -exec echo {}

…并将结果传输至

./indexer.sh \;

结果,find看到{}没有\;并且失败。(indexer.sh看到一个多余的;参数并忽略它。)

为了纠正你的误解,你必须这样做......

find . -type f -exec sh -c 'echo "{}"|./indexer.sh' \;

...因为这是将该管道视为单个命令的唯一方法。

当然,这太过分了。如果你想indexer.sh为每个 MP4 文件运行一次,请@sudodus 的建议并彻底避开管道。

答案3

需要\;放置在管道之前。由于我没有zsh,并且您的问题带有标签bash,因此我将使用它bash作为示例。

索引器

#!/bin/bash

while read foo
do
    echo "You entered '$foo'"
done

执行示例

$ find . -type f -iname '*.mp4' -exec echo {} \; |./indexer.sh
You entered './subdirectory/d.mp4'
You entered './subdirectory/c.mp4'
You entered './b.mp4'
You entered './a.mp4'

优化

可以通过删除 find 后面的 和末尾的.整个部分来优化此 find 用例。如果没有它,find 的输出将是相同的。-exec

$ find -type f -iname '*.mp4' |./indexer.sh
You entered './subdirectory/d.mp4'
You entered './subdirectory/c.mp4'
You entered './b.mp4'
You entered './a.mp4'

答案4

如果你因为某种原因不能或不想改变indexer.sh,你也可以明确说明你的迭代

find . -type f -iname '*.mp4' | while read file; do echo $file | ./indexer.sh; done

我经常使用这种模式。IFS如果文件名中有空格,您可能需要设置,但我认为其他解决方案也会遇到同样的问题。

相关内容