我正在尝试将目录结构中的选定文件复制为重复目录中的符号链接,例如
从这样的目录结构:
../1/a/data1.txt
../1/a/file1.txt
../1/a/b/file2.txt
做这个:
../2/a/file1.txt -> ../../1/a/file1.txt
../2/a/b/file2.txt -> ../../2/a/b/file1.txt
例如,保留目录树并跳过匹配各种模式的文件。
当我从目标目录 (../2/a) 使用 GNU cp 替换相对路径时,一切都按我想要的方式工作,除了它复制 data1.txt:
gcp -rs $(cd ../..; pwd)/1/a/* $PWD/
但是当我在 find + xargs 中使用它来排除某些文件时,
find -X -f $(cd ../..; pwd)/1/a \! -name '*data*' -type f | xargs -t -n1 -I % gcp -s -t $PWD/ %
我明白了:
../2/a/file1.txt -> ../1/a/file1.txt
../2/a/file2.txt -> ../1/a/b/file2.txt
例如,目录结构没有被复制。我可以想象繁琐的解决方法,但我一定错过了 xargs 语法中的一些重要内容。 (我想使用查找,因为某些日期之前和之后的文件会得到不同的处理。)
我的解决方案是粗略地调用子shell、构造路径、创建目录、创建链接(例如,未使用此处的示例进行测试):
find $(cd ../..; pwd) -type f \! -name '*data*' -print0 | xargs -0 bash -c
'while [ -n "$1" ]; do
TMP="${1%$(basename $1)}";
mkdir -p "${TMP/1/2}";
gcp -s "$1" "${1/1/2}";
shift;
done;' "bash"
因为这是在脚本内调用的,所以在命令之前我导出了相关的路径名(这里的“1”和“2”实际上是 $PATH1、$PATH2;在这个示例中,$1 的 b/c 与“1”和“2”令人困惑”)。
答案1
如果您不使用参数递归复制目录-r
,cp
则不会为您创建任何中间目录。 (仅仅添加是-r
行不通的;除非源是一个目录,否则它没有效果)。
您可以尝试-r
GNU 的选项ln
(“创建相对链接”),并使用mkdir -p {dirname}
.例子:
# usage mklinks from to [opts/predicates for find ..]
mklinks(){
from=$1; shift
to=$1; shift
find "$from" -type f "$@" -print0 | from=$from to=$to gxargs -0 sh -c '
for a; do
t="$to/${a#$from}"; b=${t##*/}
mkdir -vp "${t%$b}" && gln -vrs "$a" "$t"
done
' sh
}
mklinks ../../1/a . \! -name '*data*'
当然,如果您使用的是 linux,请更改gxargs
为xargs
和。gln
ln