如何將多個參數從find -exec
傳遞給bash -c
子shell?
有沒有辦法將多個參數從
find -exec
一個bash -c
子shell傳遞?鑑於此工作呼叫將搜尋與 glob 模式(例如)匹配的所有影片
"*dogs.mp4
,然後ffmpeg
在子 shell 中執行,並在文件已存在的情況下進行檢查和警告:find . -iname "*.mp4" -exec bash -c 'if [[ -f "${1%.*}_540.mp4" ]]; then echo "Already exists: $1"; else ffmpeg -i "$1" -vf "scale=540:-1" "${1%.*}_540.mp4" ; fi ;' _ {} +
為了避免對我替換的大小進行硬編碼
540
,$2
然後在{}
(to_ {} 540 +
) 之後將大小作為參數傳遞,以便命令變為:find . -iname "*.mp4" -exec bash -c 'if [[ -f "${1%.*}_$2.mp4" ]]; then echo "Already exists: $1"; else ffmpeg -i "$1" -vf "scale=%2:-1" "${1%.*}_%2.mp4" ; fi ;' _ {} 540 +
上面的行拋出一個錯誤
find: -exec: no terminating ";" or "+"
::我的理解是
{}
文件名的佔位符和{} +
(或{} \;
)必須在命令的末尾。在這種情況下,如何將附加參數傳遞給
bash -c
from-exec
子句?
你不能在if 你使用;*之後加上參數。*檢查規格:
{}``+
-exec … 只有緊跟在僅包含兩個字元“{}”的參數之後的加號才能標點主表達式的結尾。加號的其他用途不應視為特殊。
此外,您將多個 args 傳遞給 shell(使用 +),但僅使用
$1
這意味著您忽略了找到的其余文件。您需要在 shell 命令中放置一個循環。有關一些範例,請參見https://unix.stackexchange.com/a/321753/135943,但總體而言,它看起來像:find dirname ... -exec sh -c 'for f do somecommandwith "$f"; done' placeholder {} +
無論如何,您都在“硬編碼”大小。您也可以在實際的 shell 命令中對其進行硬編碼;然後在最後的參數列表中硬編碼它更容易。但是,如果您堅持,您可以通過
540
代替您的下劃線(即代替上述命令中的“佔位符”),並$0
從 shell 命令內部訪問它。
find ... -exec
對於更一般的問題,當您將所有找到的文件傳遞給 shell 命令並希望在循環中處理它們時,如何將額外的參數傳遞給嵌入在命令中的 shell 命令,可以這樣做:find dirname ... -exec sh -c 'arg1="$1"; arg2="$2"; shift 2; for f do somecommandwith "$f" "$arg1" "$arg2"; done' placeholder firstextraarg secondextraarg {} +
但真正的問題是,你為什麼要這樣做? 您可以更輕鬆地將“firstextraarg”和“secondextraarg”值直接放在 shell 命令中:
find dirname ... -exec sh -c 'for f do somecommandwith "$f" firstextraarg secondextraarg; done' placeholder {} +