2010-01-23 2 views
4

У меня есть иерархия каталогов с кучей файлов. Некоторые из каталогов начинаются с .. Я хочу скопировать иерархию в другое место, оставив все файлы и директории, начинающиеся с .Как скопировать каталог, за исключением всех скрытых файлов в Perl?

Как это можно сделать?

ответ

0

Glob игнорирует файлы точек по умолчанию.

perl -lwe'rename($_, "foo/$_") or warn "failure renaming $_: $!" for glob("*")'

+0

это не копия, это движение, и это не является рекурсивным. –

+0

glob не игнорирует скрытые файлы, он просто возвращает файлы, которые вы запрашиваете. Это шаблон «*», который не соответствует ведущему. , Небольшая нить, но важно знать, кто что игнорирует. :) –

+0

Функция игнорирует записи каталога. readdir, и он есть, используйте glob-оболочку в стиле оболочки с bsd_glob, и это не так, используйте текст или dos glob, и это так. – Anonymous

3

Я думаю, что вы хотите File::Copy::Recursive «s rcopy_glob():

rcopy_glob()

Эта функция позволяет задать шаблон, подходящий для Glob языка Perl(), как в первый аргумент. Впоследствии каждый путь , возвращаемый glob(), perl получает rcopy().

Он возвращает и массив, чьи элементы: массив refs, содержащий значение значения каждого вызова rcopy().

Он заставляет поведение, как будто $ Файл :: Копировать :: Рекурсивный :: CPRFComp is true.

+0

Я не мог понять, как на самом деле использовать rcopy_glob для этого, и не смог найти пример в Интернете. Как вы на самом деле используете rcopy_glob для достижения этого? –

3

Если вы в состоянии решить эту проблему без Perl, вы должны зарегистрироваться rsync. Он доступен в Unix-подобных системах, в Windows через cygwin и, возможно, в качестве автономного инструмента для Windows. Он будет делать то, что вам нужно, и многое другое.

rsync -a -v --exclude='.*' foo/ bar/ 

Если вы не являетесь владельцем всех файлов, используйте -rOlt вместо -a.

0

Код ниже выполняет задание простым способом, но не обрабатывает символические ссылки, например.

#! /usr/bin/perl 

use warnings; 
use strict; 

use File::Basename; 
use File::Copy; 
use File::Find; 
use File::Spec::Functions qw/ abs2rel catfile file_name_is_absolute rel2abs /; 

die "Usage: $0 src dst\n" unless @ARGV == 2; 
my($src,$dst) = @ARGV; 

$dst = rel2abs $dst unless file_name_is_absolute $dst; 
$dst = catfile $dst, basename $src if -d $dst; 

sub copy_nodots { 
    if (/^\.\z|^[^.]/) { 
    my $image = catfile $dst, abs2rel($File::Find::name, $src); 

    if (-d $_) { 
     mkdir $image 
     or die "$0: mkdir $image: $!"; 
    } 
    else { 
     copy $_ => $image 
     or die "$0: copy $File::Find::name => $image: $!\n"; 
    } 
    } 
} 

find \&copy_nodots => $src; 
0
cp -r .??* 

почти идеально, потому что он пропускает файлы, начинающиеся с. и за ним следует один знак. как - .d или .e

echo .[!.] .??* 

это еще лучше

или:

shopt -s dotglob ; cp -a * destination; shopt -u dotglob 
Смежные вопросы