2012-03-31 2 views
0

Я могу найти и скопировать все файлы в заданную папку с помощью команды find -exec. Но мне нужно найти и скопировать все файлы в заданном пути вместе со своей папкой, в которой она была сохранена. Так ....копировать файлы вместе с их (последними) папками

/path/to/file/is/abc.txt 
/another/file/is/here/xyz.txt 

Мне нужно скопировать эти 2 файла вместе с их пути к следующей папке:

/MySQL/данные/

Новая структура файла будет выглядеть следующим образом. ..

/mysql/data/is/abc.txt 
/mysql/data/here/xyz.txt 

Это делается для того, чтобы избежать возможной перезаписи дубликатов имен файлов. Имена последних папок будут уникальными, но имена файлов могут быть одинаковыми.

Каков наилучший способ для этого?

ответ

3

Вот краткое сценарий с довольно длинным объяснением *, чтобы сопровождать его.

for oldpath in $your_file_list; do 
    mv ${oldpath} /mysql/data${oldpath##$(dirname $(dirname $oldpath))} 
done 

Как это работает

  • dirname The утилита удаляет все вплоть до последнего косую черту (/) с пути. Вызов его дважды приведет к удалению всего до и включая косую черту от второго до последнего.

  • Идиома $(command with params) выполняет command с параметрами with params и возвращает выход.

  • Идиома ${var##prefix} возвращает содержимое переменной var с prefix удален.

Шаг за шагом анализа

Если oldpath/path/to/file/is/abc.txt является, то:

  • dirname $oldpath является /path/to/file/is
  • dirname $(dirname $oldpath) является /path/to/file
  • ${oldpath##$(dirname $(dirname $oldpath))} является /is/abc.txt

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


*Элегантный (прил.) программное обеспечение: любое программное обеспечение, которое реализует алгоритм, чье объяснение больше, чем само осуществление.

1

Вам понадобится сценарий/программа для этого решения.

Быстрый пример питон следующим образом:

import os 
import shutils 
src_root = '/path/to/walk/' 
dst_root = '/mysql/data/' 
for root,dirs,files in os.walk(src_root): 
    for file in files: 
     dst_path = os.path.split(root)[1] 
     dst_path = os.path.join(dst_root, dst_path) 
     os.makedirs(dst_path) 
     src = os.path.join(root,i file) 
     dst = os.path.join(dst_path, file) 
     shutils.copyfile(srd, dst) 
1

Это может работать для вас:

a=/mysql/data 
sed 's|.*\(/[^/]*/[^/]*\)|mv -v & '"$a"'\1|' file 
mv -v /path/to/file/is/abc.txt /mysql/data/is/abc.txt 
mv -v /another/file/is/here/xyz.txt /mysql/data/here/xyz.txt 

Исследование вывод, и если все в порядке, а затем запустить:

sed 's|.*\(/[^/]*/[^/]*\)|mv -v & '"$a"'\1|' file | bash 
0

Если вы хотите скопировать файл, сначала вам нужно создать для него каталог. Вы можете сделать это, используя команду одиночного поиска, но я не уверен в эффективности этого решения?

#!/bin/bash 
# $1 - destination 

find $1 -type f -exec bash -c ' 
    dest="$2";       # $2 is second argument passed to the script 
    dir=$(basename $(dirname $1));   
    mkdir $dest/$dir 2>/dev/null;   
    cp $1 "$dest/$dir/";     
' -- {} $2 \;       # {} = $1 in bash '..' and $2=$2 

использование: ./copy copy_from copy_to

редактировать: , что выглядит лучше:

#!/bin/bash 

dest=$2 
from=$1 

# copy_file from dest 
copy_file() { 
dir=$(basename $(dirname $from)) 
mkdir $dest/$dir 
cp $from $dest/$dir 
} 

find $from -type f | while read file; do copy_file $file $dest; done 
Смежные вопросы