Dòng lệnh Linux. Di chuyển tất cả các tệp và thư mục trong thư mục, ngoại trừ một số tệp và thư mục


8

Tôi có một thư mục Atrong đó có các file và thư mục, tôi muốn di chuyển tất cả các tập tin và thư mục vào thư mục khác B, trừ file, file2, directory, và directory2.

Điều này có thể giải quyết như thế nào?

Câu trả lời:


11

Với zsh:

setopt extendedglob # best in ~/.zshrc
mv A/^(file|directory)(|2)(D) B/

(các tệp (D)bao gồm dấu chấm (ẩn)).

Với bash:

shopt -s extglob dotglob failglob
mv A/!(@(file|directory)?(2)) B/

Với ksh93

(FIGNORE='@(.|..|@(file|directory)?(2))'; mv A/* B)

Tôi thậm chí không muốn nghĩ về việc bạn phải dành bao nhiêu thời gian cho mỗi vỏ để học điều này! Câu trả lời chính xác!
jpaugh

10

những gì tôi thường làm

cd A
ls > a

(giả sử bạn không có tệp 'a').

vi a

loại bỏ bất cứ tập tin hoặc thư mục nào được giữ đúng vị trí

mv $(<a) B

Cảm ơn câu trả lời, tôi nghĩ rằng một số chuyên gia có thể có một số lệnh / "một lớp lót" ít gây rắc rối hơn.
một cái gì đó

1
Nó phụ thuộc, nếu tôi phải làm điều đó một lần (giải pháp của tôi) hoặc nhiều lần giải pháp @ Falko.
Archemar

2
@s SomethingS Something Giải pháp này cho phép bạn kiểm tra những gì bạn sắp làm trước khi bạn làm điều đó. Đừng đánh giá thấp điều đó.
Ben

1
@Ben, hãy cẩn thận mặc dù bạn phải kiểm tra xem tên tệp không chứa trống hoặc ký tự đại diện hay không bắt đầu bằng -. Bạn sẽ không thể phát hiện ra tên tệp có chứa các ký tự dòng mới và nó sẽ bỏ qua các tệp ẩn.
Stéphane Chazelas

2
Điều này có thể nguy hiểm vì một lý do nữa: nếu lslà bí danh ls -F(thường gặp khi không sử dụng màu sắc), các đường dẫn nguồn có thể dẫn đầu /, có thể có tác dụng phụ nghiêm trọng - xem "Cảnh báo" và "Chém chém" trong info mv(hoặc pinfo mv, nhưng không phải trong man mv)
Volker Siegel

5

Bạn có thể sử dụng findvới các biểu thức loại trừ:

find . ! -name . -prune ! -path ./file \
                        ! -path ./file2 \
                        ! -path ./directory \
                        ! -path ./directory2 \
     -exec mv {} your_destination \;

Giải pháp này được lấy cảm hứng từ câu hỏi này .


Tôi nhận được: find: vị ngữ không xác định `-E 'nếu tôi sao chép và dán giải pháp của bạn và sửa đổi" your_destination "cho phù hợp.
vài thứ gì đó

1
@s SomethingS Something: Tôi đoán bạn có thể bỏ -Etùy chọn. Nhưng có thể có sự khác biệt giữa các hệ thống của chúng tôi, vì tôi hiện đang dùng OSX.
Falko

2
ls | egrep -v '(file|file2|directory|directory2)' | xargs -i mv {} ../B/

1

Nếu ./A./Bnằm trên cùng một hệ thống tệp nếu các tệp này chưa tồn tại trong ./B:

file file2 directory directory2

... thì hoạt động này chỉ là nguyên tử:

cd ./A; mv * ../B
for mv in file file2 directory directory2
do mv ../B/"$mv" .
done

Nếu không, thì có ít nhất 8 bản sao thiết bị chéo bổ sung được thực hiện với bộ lệnh trên.


Không biết bất kỳ vỏ nào đảm bảo điều này thực sự là nguyên tử. Tuy nhiên, nó sẽ "thực sự rất nhanh" nếu trên cùng một fs. EDIT - đó là mỗi mv có thể là nguyên tử nếu trên cùng một fs nhưng toàn bộ mv không phải là nguyên tử
Brandin

@Brandin - vỏ không liên quan đến việc đó có phải là hoạt động nguyên tử hay không. mv unlinksrenameskhi không vượt qua các nhà phát triển - về cơ bản, nó chỉ ảnh hưởng đến răng. Nhưng cái vỏ không vào được.
mikeerv

0

$ sudo mv (tên thư mục nguồn) AB (tên người dùng đích)

ví dụ: tạo thư mục trống một số thư mục con a 1) sudo mkdir -p A / {b / {a, b, c}, c, d}

2) ls A /

bcd

3) sudo mkdir B

5) sudo mv a (thư mục) b (thư mục)


0

Bạn có thể sử dụng một mảng bash để lưu trữ những mảng nào bạn muốn bỏ qua và sau đó sử dụng containsElementhàm được trình bày ở đây :

$ skiplist=(file file2 directory directory2)
$ for f in *; do if containsElement "$f" "${skiplist[@]}"; then continue; fi;
mv -v "$f" B; done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.