![find :处理目录并将结果写入找到的目录](https://linux22.com/image/194937/find%20%EF%BC%9A%E5%A4%84%E7%90%86%E7%9B%AE%E5%BD%95%E5%B9%B6%E5%B0%86%E7%BB%93%E6%9E%9C%E5%86%99%E5%85%A5%E6%89%BE%E5%88%B0%E7%9A%84%E7%9B%AE%E5%BD%95.png)
我想找到一个目录,对其应用命令,结果应该通过管道传输到这个找到的目录中。
假设find -type d
给出
.
./cortexa53-crypto-mx8mp
./cortexa53-crypto
./imx8mp_sp
./all
我考虑做这样的事情:
find -type d -exec '~/bin/opkg-utils/opkg-make-index {} | gzip > {}/package.gz' \;
结果如下:
find: '~/bin/opkg-utils/opkg-make-index ./cortexa53-crypto-mx8mp | gzip > ./cortexa53-crypto-mx8mp/package.gz': No such file or directory
但是如果我执行该命令(那么里面是什么' '
) - 它可以工作!?!?
额外问题:如何避免找到.
?
答案1
如果您需要执行比带有参数 from 的简单命令更复杂的命令-exec
,请在内联脚本中执行此操作:
find . -type d -exec sh -c '
tmpfile=$(mktemp) || exit
trap "rm -f \"\$tmpfile\"" EXIT
for dirpath do
"$HOME"/bin/opkg-utils/opkg-make-index "$dirpath" | gzip -c >"$tmpfile" &&
cp -- "$tmpfile" "$dirpath"/package.gz
done' sh {} +
这会将批量目录路径作为参数传递给内联sh -c
脚本。这个简短的脚本循环遍历这些路径,对于每个路径,它将调用您的实用程序并将压缩输出写入临时文件。写入文件后,它被移动到目录中,并继续循环到下一个目录。
请注意,这将递归到子目录中。
为了避免发现.
使用! -path .
:
find . ! -path . -type d -exec sh -c '...' sh {} +
或者,对于 GNU find
(和其他一些),使用-mindepth 1
:
find . -mindepth 1 -type d -exec sh -c '...' sh {} +
为了避免递归到子目录,请-prune
在找到目录后立即使用:
find . ! -path . -type d -prune -exec sh -c '...' sh {} +
或者,对于 GNU find
,使用-maxdepth 1
:
find . -mindepth 1 -maxdepth 1 -type d -exec sh -c '...' sh {} +
但是,如果您只对单个目录感兴趣,而不使用递归,那么您可以只使用 shell 循环:
shopt -s nullglob dotglob
tmpfile=$(mktemp) || exit
trap 'rm -f "$tmpfile"' EXIT
for dirpath in */; do
dirpath=${dirpath%/}
[ -h "$dirpath" ] && continue
"$HOME"/bin/opkg-utils/opkg-make-index "$dirpath" | gzip -c >"$tmpfile" &&
cp -- "$tmpfile" "$dirpath"/package.gz
done
这本质上与执行的内联脚本中的循环相同find
,但它是一个bash
脚本,并且确实需要执行一些原本find
要执行的工作(启用通配隐藏名称、检查它$dirpath
不是符号链接等)。 )