Tôi muốn sao chép tất cả các tệp trong một thư mục ngoại trừ một số tệp trong một thư mục con cụ thể. Tôi đã nhận thấy rằng lệnh 'cp' không có tùy chọn --exclude. Vì vậy, làm thế nào tôi có thể đạt được điều này?
tar -c | tar -x
?
Tôi muốn sao chép tất cả các tệp trong một thư mục ngoại trừ một số tệp trong một thư mục con cụ thể. Tôi đã nhận thấy rằng lệnh 'cp' không có tùy chọn --exclude. Vì vậy, làm thế nào tôi có thể đạt được điều này?
tar -c | tar -x
?
Câu trả lời:
rsync rất nhanh và dễ dàng:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
Bạn có thể sử dụng --exclude
nhiều lần.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
Lưu ý rằng thư mục thefoldertoexclude
sau --exclude
tùy chọn có liên quan đến sourcefolder
, tức là , sourcefolder/thefoldertoexclude
.
Ngoài ra, bạn có thể thêm -n
chạy khô để xem những gì sẽ được sao chép trước khi thực hiện thao tác thực sự và nếu mọi thứ đều ổn, hãy xóa -n
khỏi dòng lệnh.
--exclude
thefoldertoexclude
liên quan đến sourcefolder
hoặc các dir làm việc hiện tại? cảm ơn
rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder
- dù sao thì hãy nâng cấp cho rsync thay vì tìm, vì bạn có thể dễ dàng sử dụng các đường dẫn tuyệt đối cho nguồn trong khi tìm thấy nó khó hơn khi sử dụng {}
trong dst.
$ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/
hoặc từ cục bộ đến từ xa$ rsync /var/www/mylocalpage/ user@example.com:/var/www/mypage
Chà, nếu loại trừ một số mẫu tên tệp nhất định phải được thực hiện bởi mọi tiện ích tệp unix-ish (như cp, mv, rm, tar, rsync, scp, ...), sẽ xảy ra sự trùng lặp lớn về nỗ lực. Thay vào đó, những điều như vậy có thể được thực hiện như một phần của Globing , tức là bằng vỏ của bạn.
man 1 bash
, / Extglob .
Thí dụ:
$ shopt -s extglob $ echo hình ảnh / * hình ảnh / 004.bmp hình ảnh / 033.jpg hình ảnh / 1276338351183.jpg hình ảnh / 2252.png $ echo hình ảnh /! (*. jpg) hình ảnh / 004.bmp hình ảnh / 2252.png
Vì vậy, bạn chỉ cần đặt một mô hình bên trong !()
, và nó phủ nhận trận đấu. Mô hình có thể phức tạp tùy ý, bắt đầu từ việc liệt kê các đường dẫn riêng lẻ (như Vanwaril hiển thị trong một câu trả lời khác) : !(filename1|path2|etc3)
, cho đến những thứ giống như regex với các ngôi sao và các lớp nhân vật. Tham khảo trang hướng dẫn để biết chi tiết.
man 1 zshexpn
, / tạo tên tệp .
Bạn có thể làm setopt KSH_GLOB
và sử dụng các mẫu giống như bash. Hoặc là,
% setopt EXTENDED_GLOB % hình ảnh phản hồi / * hình ảnh / 004.bmp hình ảnh / 033.jpg hình ảnh / 1276338351183.jpg hình ảnh / 2252.png % hình ảnh phản hồi / * ~ * .jpg hình ảnh / 004.bmp hình ảnh / 2252.png
Vì vậy, x~y
phù hợp với mô hình x
, nhưng loại trừ mô hình y
. Một lần nữa, để biết chi tiết đầy đủ tham khảo manpage.
Các cá vỏ có một câu trả lời đẹp hơn nhiều như thế này:
🐟 cp (chuỗi khớp -v '* .excluded.names' - srcdir / *) Destdir
Gõ cp *
, nhấn CtrlX*và chỉ xem những gì xảy ra. Tôi hứa là không có hại
zsh
mặc dù nó hoạt động .
setopt -u extglob
.
Tại sao sử dụng rsync
khi bạn có thể làm:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
Điều này giả định cấu trúc thư mục đích giống như của nguồn.
-path
đối số để kiểm tra hệ thống phân cấp đường dẫn, không phải là trò chơi
find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
rsync
? Vì nó có thể không có trong hệ thống! trong khi find
, cp
luôn luôn ở vị trí của họ Hoặc bạn từ loại người, những người đã cài đặt 2gigs thứ để làm những việc đơn giản?
cp -r `ls -A | grep -v "c"` $HOME/
# $1 = source path # $2 = destination path # $3 = filter copy_from_source_to_destination_except_filter() { cp -r $(ls -A $1 | grep -v -w $3 | awk -v path=$1 '{printf "%s/%s ", path, $1}') $2 }
Cách dễ nhất tôi tìm thấy, nơi bạn có thể sao chép tất cả các tệp trừ tệp và thư mục chỉ bằng cách thêm tên của chúng trong ngoặc đơn:
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
-bash: !: event not found
Mở rộng trên nhận xét của mvds , điều này làm việc cho tôi
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
Nó liên quan đến thư mục nguồn.
Điều này sẽ loại trừ thư mục source/.git
khỏi bị sao chép.
rsync -r --exclude '.git' source target
rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
và trước tiên hãy thử với tùy chọn -n để xem những gì sẽ được sao chép
Tôi giả sử bạn đang sử dụng bash hoặc dash. Điều này sẽ làm việc?
shopt -s extglob # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination
Thực hiện một ls không bao gồm các tệp bạn không muốn và sử dụng đó làm đối số đầu tiên cho cp
ls
và chỉ cần làm cp !(file1|file1) dest
.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
rsync
thực sự là khá khó khăn phải làm nhiều bài kiểm tra để làm cho nó hoạt động.
Giả sử bạn muốn sao chép /var/www/html
vào /var/www/dev
nhưng cần loại trừ /var/www/html/site/video/
thư mục có thể do kích thước của nó. Lệnh sẽ là:
rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Một số cảnh báo :
/
trong nguồn là cần thiết, nếu không, nó cũng sẽ sao chép thư mục nguồn chứ không phải nội dung của nó và trở thành /var/www/dev/html/xxxx
, có thể không phải là điều bạn muốn.Đường --exclude
dẫn có liên quan đến nguồn trực tiếp. Ngay cả khi bạn đặt đường dẫn tuyệt đối đầy đủ, nó sẽ không hoạt động.
-v
dành cho verbose, -a
dành cho chế độ lưu trữ, có nghĩa là bạn muốn đệ quy và muốn bảo tồn hầu hết mọi thứ.
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Chỉnh sửa: quên loại trừ đường dẫn đích (nếu không nó sẽ sao chép đệ quy).
Đây là một sửa đổi câu trả lời của Linus Kleen. Câu trả lời của anh ấy đã không làm việc cho tôi vì sẽ có một. được thêm vào trước đường dẫn tệp mà cp không thích (đường dẫn sẽ trông giống như nguồn / .destination / tệp).
Lệnh này đã làm việc cho tôi:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
lệnh --parents bảo tồn cấu trúc thư mục.
Chỉ cần di chuyển nó tạm thời vào một thư mục ẩn (và đổi tên nó sau, nếu muốn).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
cp
và vỏ POSIX tiêu chuẩn như thế nào sh
.
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
Tôi sử dụng vòng lặp "do while" để đọc đầu ra của lệnh find. Trong ví dụ này, tôi phù hợp (thay vì loại trừ) một số mẫu nhất định vì có số lượng mẫu phù hợp hạn chế hơn mà tôi muốn hơn là tôi không muốn. Bạn có thể đảo ngược logic bằng một -not ở phía trước các cờ -iname:
find . -type f -iname "*.flac" -o -print0 -iname "*.mp3" -print0 -o -iname "*.wav" -print0 -o -iname "*.aac" -print0 -o -iname "*.wma" -print0 | while read -d $'\0' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done
Tôi sử dụng ở trên để sao chép tất cả các tệp loại nhạc mới hơn trên máy chủ của mình so với các tệp trên Western Digital TV Live Hub mà tôi đã gắn tại / media / wd. Tôi sử dụng ở trên vì tôi có rất nhiều tệp DVD, mpeg, v.v. mà tôi muốn loại trừ VÀ vì lý do nào đó rsync trông giống như nó đang sao chép, nhưng sau khi tôi nhìn vào thiết bị wd, các tệp không có mặc dù không có lỗi trong rsync với lệnh này:
rsync -av --progress --exclude=*.VOB --exclude=*.avi --exclude=*.mkv --exclude=*.ts --exclude=*.mpg --exclude=*.iso --exclude=*ar --exclude=*.vob --exclude=*.BUP --exclude=*.cdi --exclude=*.ISO --exclude=*.shn --exclude=*.MPG --exclude=*.AVI --exclude=*.DAT --exclude=*.img --exclude=*.nrg --exclude=*.cdr --exclude=*.bin --exclude=*.MOV --exclude=*.goutputs* --exclude=*.flv --exclude=*.mov --exclude=*.m2ts --exclude=*.cdg --exclude=*.IFO --exclude=*.asf --exclude=*.ite /media/2TB\ Data/data/music/* /media/wd/network_sync/music/
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir
Phần đầu tiên ls
tất cả các tệp nhưng ẩn các tệp cụ thể với cờ -I
. Đầu ra của ls
được sử dụng làm đầu vào tiêu chuẩn cho phần thứ hai. xargs
xây dựng và thực hiện lệnh cp -rf -t destdir
từ đầu vào tiêu chuẩn. cờ -r
có nghĩa là sao chép các thư mục theo cách đệ quy, -f
có nghĩa là sao chép các tệp cưỡng bức sẽ ghi đè lên các tệp trong destdir
, -t
chỉ định sao chép thư mục đích vào.
cp -r ls -A | grep -v "Excluded_File_or_folder"
../$target_location -v