2016-01-15 2 views
1

Я ищу для создания копии дерева папок с пустыми файлами. Файлы в исходных папках не пусты, но я хочу, чтобы файлы в папках назначения были пустыми. (Я не думаю, что могу просто использовать мягкую/жесткую ссылку, потому что Я нахожусь в Mac OS X, правильно?) Это для отслеживания содержания многих внешних жестких дисков с большим количеством больших видеофайлов в них.Копировать дерево каталогов с пустыми файлами

Я нашел rsync -a -f"+ */" -f"- *" source/ destination/, чтобы скопировать папки, но я не нашел способ создать пустые файлы (я пробовал tcsh foreach, но он не удался из-за наличия пробелов в имени папок).

Благодарим за помощь!

+0

Какова цель этого? Похоже на достижимую проблему, но довольно странно, что это звучит как [проблема XY] (http://mywiki.wooledge.org/XyProblem). Что вы на самом деле пытаетесь сделать? Если вы хотите отслеживать, какие файлы находятся на внешних дисках, почему бы просто не хранить текстовые файлы с выходом 'find' на каждом из них? – ghoti

ответ

2

Опираясь на ответ от ursusd8, вот рекурсивным решение, которое будет работать в Баш версии 4, если у вас есть, что установлен ...

shopt -s globstar 
cd /path/to/source/ 
for f in **/*; do 
    mkdir -p "/path/to/target/${f%/*}" # make the containing directory if required 
    touch "/path/to/target/$f"   # make a zero-length file 
done 

Это запускает mkdir команду много раз больше, чем требуется, но это быстро. Обратите внимание, что bash 4 может быть недоступен в вашей системе, если вы явно не установили его, используя MacPorts или homebrew или тому подобное.

Более длинная Альтернатива была бы отделить этапы создания вашего дерева каталогов и трогая файлы:

cd /path/to/source/ 
find . -type d -exec mkdir -p /path/to/target/{} \; 
find . -type f -exec touch /path/to/target/{} \; 

Обратите внимание, что это два этапа find решения не использует bashisms, и, вероятно, может работать в любой оболочке ,

0

Вот решение, которое даже может обрабатывать необычные имена файлов правильно (например, имена файлов с новой строкой внутри и т.д.)

Это будет первым создать дерево каталогов, а затем создать пустые файлы. необходимы дополнительные внешние команды, кроме find, mkdir и touch.

#!/bin/bash 

# IMPORTANT: SOURCE and DESTINATION have to be absolute pathes 
# To fix the missing parameter -printf of find in mac os x, 
# i used a technique to reproduce the functionality. 
# But now it IS IMPORTANT that both of these variables contain an absolute path! 

SOURCE="/home/you/source_dir/" 
DESTINATION="/where/ever/destination_dir/" 

#first 'copy' the directory tree 
while 
    IFS="" read -r -d '' -u 9 dir 
do 
    #remove the $SOURCE part 
    dir="${dir#${SOURCE}}" 

    mkdir "${DESTINATION}/${dir}" 
done 9< <(find "${SOURCE}" -type d -print0) 

#then create empty files inside the new tree 
while 
    IFS="" read -r -d '' -u 9 file 
do 
    #remove the $SOURCE part 
    file="${file#${SOURCE}}" 

    touch "${DESTINATION}/${file}" 
done 9< <(find "${SOURCE}" -type f -print0) 

EDIT: Удалено использование -printf из find инструмента, как это, казалось бы, не существует в Mac OS X - используется подстановка параметров Баша, чтобы воссоздать поведение.

+1

Спасибо! Но find -printf, похоже, не существует в Mac OS X –

+0

@ElieV Я могу переписать этот скрипт, чтобы он работал для вас.Мне просто нужно знать, могу ли я полагаться на правильный 'bash', или вам нужно сделать это в' tcsh'? – bricklore

+0

Еще раз спасибо! В OS X у меня есть версия bash 3.2.57 (версия для ОС X Yosemite) и tcsh v6.17.00 (версия для ОС X Yosemite) –

0

Вы можете попробовать использовать touch в течение цикла:

cd /PATH/TO/SOURCE/FOLDER/ 
for f in *; 
do touch /PATH/TO/DEST/FOLDER/$f; 
done 

EDIT: Код выше даст вам все файлы и папки в /SOURCE/FOLDER, но не рекурсивным. Для создания пустых файлов только для исходных файлов и создать дерево каталогов (все вложенные папки), вы можете использовать:

FILES=$(find /PATH/TO/SOURCE/FOLDER/ -type f) 
for f in $FILES; 
do touch /PATH/TO/DEST/FOLDER/$f; 
done 

Я надеюсь, что это помогает!

+0

Спасибо за ваш ответ. Я просто попытался, но могу ли я сделать это рекурсивно (создать пустые файлы для всех файлов в подпапках? –

+0

Если вы используете 'bash' 4 или новее, используйте' shopt -s globstar; для f в **/*; do' – chepner

+0

You может попробовать что-то вроде этого: 'FILES = $ (найти/PATH/TO/SOURCE/FOLDER/-type F) для е в $ FILES, сделать сенсорную/PATH/TO/DEST/FOLDER/$ е; done' Это должно создать дерево пустых файлов. – ursusd8

Смежные вопросы