копировать файлы с базовым каталогом - PullRequest
0 голосов
/ 26 мая 2018

Я ищу в определенных каталогах и подкаталогах новые файлы, хочу скопировать файлы.Я использую это:

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 голосов
/ 26 мая 2018

Я нашел способ обойти это:

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}' {} \;
0 голосов
/ 26 мая 2018

Поскольку вы не можете использовать rsync или причудливые параметры GNU, вам нужно свернуть свой собственный с помощью оболочки.

Команда find позволяет вам запустить полную оболочку в -exec, так что выдолжно быть хорошо идти с однострочником для обработки имен.

Если я правильно понимаю, вы хотите, чтобы только родительский каталог, а не полное дерево, копировался в цель.Следующее может сделать:

#!/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 также не поддерживается Solaris и может быть безопасно проигнорирован.

0 голосов
/ 26 мая 2018

Попробуйте протестировать с помощью rsync -R, например:

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

От rsync man:

-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. 
0 голосов
/ 26 мая 2018

Проблема с ответами @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!;)

0 голосов
/ 26 мая 2018

Флаг --parents должен помочь:

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