我想对$SOURCE
to的第一个节点中的所有目录和文件进行符号链接$HOME/Destination/
。伪代码
ln -s $SOURCE/* exceptThese $HOME/Destination/
提议
find $HOME ! -name Data -o -name Labs -exec \
ln -s "$0" $HOME/Documents/
我不确定的地方$0
。
如何对除第一个节点之外的所有节点进行符号链接?
答案1
$HOME/this
如果您的意思是要从、$HOME/there/that
、等创建符号链接,$HOME/Data/ddd
而不是$HOME/Data
或$HOME/somewhere/Labs
,那么匹配的标准应该是
find "$HOME" ! \( -name Data -o -name Labs \) -exec …
你漏掉了括号。并置绑定比-o
这样更紧密,因此仅对-name Data -o name Labs -exec …
名为 的文件执行命令Labs
(除了名为 的文件Data
,但无论如何它们都不能被命名Labs
)。
Data
如果您打算排除和下的所有文件Labs
,那么您需要该-prune
操作,该操作告诉find
您完全跳过目录,而不是递归地遍历它们。
find "$HOME" \( -name Data -o -name Labs \) -prune -o -exec …
这排除了根称为 的任何子树Data
,而不仅仅是$HOME/Data
。如果您只想排除$HOME/Data
而不是 eg $HOME/sub/data
,您可以使用-path
(如果您的find
实现支持它)。
find "$HOME" \( -path "$HOME/Data" -o -path "$HOME/Labs" \) -prune -o -exec …
现在,对于-exec
部分。在-exec
操作中,使用{}
(在其自身的参数中)代表find
找到的路径。在要运行的命令末尾放置一个;
(加引号,以便将其传递给 shell ,而不是由 shell 解析)。find
find … -exec ln -s {} "$HOME/Documents/" \;
如果你仅有的想要直接在下面的文件$HOME
而不是子目录中的文件,那么这find
不是完成这项工作的最佳工具:它是为递归遍历而设计的。请改用 shell 循环。请注意,该模式*
会跳过点文件,即名称以 开头的所有文件.
,并且该模式.*
会匹配所有点文件加上.
和..
,这两个文件需要显式跳过。
for x in ~/* ~/.*; do
case "${x##*/}" in
.|..|Data|Labs) continue;; # Skip those entries
esac
ln -s "$x" "$HOME/Documents";;
done
答案2
在 Bash 中,您可以通过启用 extglob 选项来做到这一点:
$ shopt -s extglob #Enables extglob
$ ls -l "$HOME"/!(Data|Labs|Documents) #Test run
$ ln -s "$HOME"/!(Data|Labs|Documents) \
"$HOME"/Documents/ #Create symlinks
$ shopt -s extglob #Disable extglob
编辑:根据您的原始帖子使用 find ,这应该有效:
$ find "$HOME" \
-mindepth 1 \
-maxdepth 1 \
! -name Data ! -name Labs ! -name Documents\
-exec ln -s {} "$HOME"/Documents/ \;
该mindepth
选项不包括根目录。该maxdepth
选项不包括子目录。每一项都! -name
排除一条路径。{}
的参数是-exec
您正在寻找的而不是$0
。
答案3
find
要为除第一个结果之外的所有发现建立链接,您可以执行以下操作:
for item in "$(find "$HOME" ! -name Data -o -name Labs | tail --lines=+2)"; do
ln -s "$item" "$HOME"/Documents/
done