使用基目录复制文件

时间:2018-05-26 12:17:10

标签: bash shell solaris solaris-10

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

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。

5 个答案:

答案 0 :(得分:1)

由于你不能使用rsync或花哨的GNU选项,你需要使用shell来自己动手。

使用find命令可以在-exec中运行完整的shell,因此您最好使用单行代码来处理名称。

如果我理解正确,您只希望将父目录而不是完整树复制到目标。以下可能会:

#!/usr/bin/env bash

findopts=(
    -type f
    -mtime -2
    -exec bash -c 'd="${0%/*}"; d="${d##*/}"; mkdir -p "$1/$d"; cp -v "$0" "$1/$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选项的脚本仍然有点笨拙,所以这里是每个文件的功能细分。请记住,在此格式中,选项从零开始编号,{}变为$0,目标目录变为$1 ...

d="${0%/*}"            # Store the source directory in a variable, then
d="${d##*/}"           # strip everything up to the last slash, leaving the parent.
mkdir -p "$1/$d"       # create the target directory if it doesn't already exist,
cp "$0" "$1/$d/"      # then copy the file to it.

我使用cp -v作为详细输出,如上面的“结果”中所示,但是IIRC也不支持它,并且可以安全地忽略它。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

尝试使用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. 

答案 3 :(得分:0)

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

> head [PushK 5, Pop]
PushK 5  -- Great!

> (\_ x -> x)PushK 5
5 -- Great!

> (\_ x -> x)(head [PushK 5, Pop])
Couldn't match expected type `t1 -> t' with actual type `Cmd'

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

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

答案 4 :(得分:0)

我找到了解决方法:

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}' {} \;