我正在尝试将命令的结果通过管道传输find
到 bash 脚本。这是为了简化(也许自动化)我一直在研究的过程。
这是我想运行的命令
find . -type f -iname '*.mp4' -exec echo {}|./indexer.sh \;
indexer.sh
是ofcchmod +x
所以它可以执行。
indexer.sh
目前包含
#!/bin/zsh
read foo
echo "You entered '$foo'"
Run Code Online (Sandbox Code Playgroud)
如果我运行$ echo foo | ./indexer.sh
我得到的输出
You entered 'foo'
但是当我运行时,find . -type f -iname '*.mp4' -exec echo {}|./indexer.sh \;
我收到以下错误消息:
find: -exec: no terminating ";" or "+"
You entered ''
Run Code Online (Sandbox Code Playgroud)
那么如何将 find, 的输出通过管道传输到我的脚本中呢?
sud*_*dus 19
我会使用参数而不是读取语句和管道来重写它,
find . -type f -iname '*.mp4' -exec ./indexer.sh {} \;
Run Code Online (Sandbox Code Playgroud)
使用以下indexer.sh,
#!/bin/zsh
echo "You entered '$1'"
Run Code Online (Sandbox Code Playgroud)
200*_*ess 18
您的误解是echo {}|./indexer.sh
被视为一个单位。事实并非如此。问题在于您的 shell在运行之前find
解释了管道。因此,它正在运行\xe2\x80\xa6
find . -type f -iname \'*.mp4\' -exec echo {}\n
Run Code Online (Sandbox Code Playgroud)\n\xe2\x80\xa6 并将结果通过管道传输到
\n./indexer.sh \\;\n
Run Code Online (Sandbox Code Playgroud)\n结果,没有find
看到,就失败了。(看到一个多余的参数并忽略它。){}
\\;
indexer.sh
;
要纠正您的误解,您必须执行 \xe2\x80\xa6
\nfind . -type f -exec sh -c \'echo "{}"|./indexer.sh\' \\;\n
Run Code Online (Sandbox Code Playgroud)\n\xe2\x80\xa6 因为这是将该管道视为单个命令的唯一方法。
\n当然,那是一个怪物。如果您想indexer.sh
为每个 MP4 文件运行一次,请采纳@sudodus 的建议并完全避免使用管道。
需要\;
放置在管道之前。由于我没有zsh
,并且您的问题被标记为bash
,因此我将使用bash
一个示例。
索引器.sh
#!/bin/bash
while read foo
do
echo "You entered '$foo'"
done
Run Code Online (Sandbox Code Playgroud)
执行示例
$ 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'
Run Code Online (Sandbox Code Playgroud)
优化
find 的这个用例可以通过删除紧接在 find 之后的部分和最后的.
整个部分来优化。-exec
如果没有它,find 的输出将是相同的。
$ 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'
Run Code Online (Sandbox Code Playgroud)