我试图找到给定路径中的所有目录,并在这些目录内创建软链接到另一个位置具有相同名称的目录。许多目录的名称中都有空格。我将以下代码拼凑在一起,只要没有空格,它似乎就可以工作。
find /some/path/* -maxdepth 0 -exec sh -c "ln -s /some/other/path/"'$(basename {})'" {}" \;
我应该如何改变它来处理空格?我的目录名称中通常没有它们,但这些镜像目录位于我的 Windows PC 上,我在其中使用空格。任何帮助是极大的赞赏!
编辑
针对cuonglm和Gilles提出的观点:
命令参数的顺序
ln -s
没有错误,但是从我的解释中我想做什么并不太清楚。对于 中的每个目录/some/path/
,我想创建一个符号链接在该目录指向 中的同名目录/some/other/path/
。/some/other/path/
也是如此,source
而且/some/path/
也是destination
。我想要这样做的原因是因为/some/path/
包含 中的目录子集/some/other/path/
,并且我想要每个目录的从子集到完整集的链接。路径中不会有太多目录,但我同意不防范它是一个毫无意义的缺陷。
我没有使用的原因
-type d
是给定路径中只有目录而不是文件,但我意识到包含它会更好。
答案1
您的命令存在一些问题:
/some/path/*
如果下面的目录太多,可能会导致参数列表太长错误/some/path
它不过滤目录或文件
它的效率非常低,因为它使用了内联脚本
sh -c
,但是-exec ... {} \;
使用
ln
错误的参数位置,将创建从to而不是to 的ln -s source dest
符号链接。source
dest
dest
source
你可以用 POSIX 方式做到这一点:
find /some/path ! -path /some/path -prune -type d -exec sh -c '
for f do
ln -s "$f" /some/other/path/"${f##*/}"
done
' sh {} +
或者如果您find
支持-maxdepth
:
find /some/path -maxdepth 1 -type d -exec sh -c '...' sh {} +
答案2
首先,始终{}
在 中用作单独的参数find -exec …
。使用适用于某些(不是所有)版本的,但不可能处理包含“不寻常”字符的文件名,例如空格、、等(具体哪些字符会导致问题取决于您使用的具体位置)。作为单独的参数传递。之后的第一个参数是.stuff{}morestuff
find
'
"
{}
{}
sh -c CODE
$0
不要忘记变量扩展周围的双引号。
find … -exec sh -c 'ln -s /some/other/path/$(basename "$0") "$0"' {} \;
(我还简化了引用,在全文中使用单引号。)
您的命令至少还存在一个问题。您正尝试在 返回的位置创建符号链接find
,通过构造,该位置已经存在符号链接。看来您打算在 下创建一个符号链接/some/other/path
,在这种情况下,您需要交换参数ln
(与 和 一样mv
,cp
现有文件在前,目标在最后)。
find /some/path/* -maxdepth 0 -exec sh -c 'ln -s "$0" /some/other/path/$(basename "$0")' {} \;
basename
您可以通过使用 shell 字符串操作结构而不是, 并sh
一次批量调用来加快速度。
find /some/path/* -maxdepth 0 -exec sh -c '
for x do
ln -s "$x" /some/other/path/${x##*/};
done' {} +
如果这是您的实际find
命令,那么find
在这里没有用。的要点find
是递归到子目录。非递归查找有时对于利用其过滤器很有用(例如,仅对特定类型的文件或在特定时间跨度内修改的文件进行操作)。但是find
没有过滤的非递归是没有意义的。
for x in /some/path/*; do
ln -s "$x" "/some/other/path/${x##*/}";
done' {} +
或者
cd /some/path
for x in *; do
ln -s "$PWD/$x" "/some/other/path/$x";
done' {} +
或者,与桀骜:
autoload -U zmv
alias zln='zmv -L'
zln -s '/some/path/*' '/some/other/path/$f:t'