使用基本目录复制文件

copy files with the base directory

我正在特定目录和子目录中搜索新文件,我想复制这些文件。我正在使用这个:

find /home/foo/hint/ -type f -mtime -2 -exec cp '{}' ~/new/ \;

复制文件成功,但在/home/foo/hint/的不同子目录中有些文件同名。 我想将文件及其基本目录复制到 ~/new/ 目录。

test@serv> find /home/foo/hint/ -type f -mtime -2 -exec ls '{}' \;
/home/foo/hint/do/pass/file.txt
/home/foo/hint/fit/file.txt
test@serv> 

~/new/ 复制后应如下所示:

test@serv> ls -R ~/new/
/home/test/new/pass/:
file.txt

/home/test/new/fit/:
file.txt
test@serv>

平台:Solaris 10。

--parents 标志应该可以解决问题:

find /home/foo/hint/ -type f -mtime -2 -exec cp --parents '{}' ~/new/ \;

尝试使用 rsync -R 进行测试,例如:

find /your/path -type f -mtime -2 -exec rsync -R '{}' ~/new/ \;

来自 rsync 人:

-R, --relative
              Use  relative  paths.  This  means that the full path names specified on the
              command line are sent to the server rather than just the last parts  of  the
              filenames. 

@Mureinik 和@nbari 的回答的问题可能是新文件的绝对路径将在目标目录中生成。在这种情况下,您可能希望在命令之前切换到基本目录,然后返回到当前目录:

path_current=$PWD; cd /home/foo/hint/; find . -type f -mtime -2 -exec cp --parents '{}' ~/new/ \; ; cd $path_current

path_current=$PWD; cd /home/foo/hint/; find . -type f -mtime -2 -exec rsync -R '{}' ~/new/ \; ; cd $path_current

这两种方式都适用于 Linux 平台。希望 Solaris 10 知道 rsync 的 -R ! ;)

由于您不能使用 rsync 或花哨的 GNU 选项,您需要使用 shell.

自己动手

find 命令可以让你在 -exec 中 运行 一个完整的 shell,所以你最好用一行代码来处理名字.

如果我没理解错的话,您只需要父目录,而不是完整的树,复制到目标。以下可能会做:

#!/usr/bin/env bash

findopts=(
    -type f
    -mtime -2
    -exec bash -c 'd="${0%/*}"; d="${d##*/}"; mkdir -p "/$d"; cp -v "[=10=]" "/$d/"' {} ./new \;
)

find /home/foo/hint/ "${findopts[@]}"

结果:

$ find ./hint -type f -print
./hint/foo/slurm/file.txt
./hint/foo/file.txt
./hint/bar/file.txt
$ ./doit
./hint/foo/slurm/file.txt -> ./new/slurm/file.txt
./hint/foo/file.txt -> ./new/foo/file.txt
./hint/bar/file.txt -> ./new/bar/file.txt

我已将 find 的选项放入 bash 数组中以便于阅读和管理。 -exec 选项的脚本仍然有点笨拙,下面是它对每个文件的作用的细分。请记住,在此格式中,选项从零开始编号,{} 变为 [=18=] 并且目标目录变为 </code>...</p> <pre><code>d="${0%/*}" # Store the source directory in a variable, then d="${d##*/}" # strip everything up to the last slash, leaving the parent. mkdir -p "/$d" # create the target directory if it doesn't already exist, cp "[=12=]" "/$d/" # then copy the file to it.

我使用 cp -v 进行详细输出,如上面 "Results" 所示,但 IIRC 它也不被 Solaris 支持,可以安全地忽略。

我找到了解决方法:

cd ~/new/
find /home/foo/hint/ -type f -mtime -2 -exec nawk -v f={} '{n=split(FILENAME, a, "/");j= a[n-1];system("mkdir -p "j"");system("cp "f" "j""); exit}' {} \;