Di chuyển tất cả các tệp ngoại trừ một


155

Làm thế nào tôi có thể di chuyển tất cả các tập tin ngoại trừ một tập tin? Tôi đang tìm kiếm một cái gì đó như:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

nơi tôi chuyển những thứ cũ sang những thứ mới - trừ Tux.png. ! -sign đại diện cho một phủ định. Có một số công cụ cho công việc?

Câu trả lời:


142

Nếu bạn sử dụng bash và extglobđặt tùy chọn shell (thường là trường hợp này):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
Tôi đã gặp sự cố khi kiểm tra lệnh cho nhiều mục: mv ~ / Linux / Cũ /! Chuyện gì thế?
Léo Léopold Hertz 준영 22/03/2016

5
@UnixBasics, hãy thử: ~ / Linux / Cũ /! (Tux.png | Tux1.png | Tux2.png)
Juliano

@Juliano Lệnh rất tuyệt! Có nhiều phép toán như OR và XOR không? Tôi giả sử một đường ống là cho AND.
Léo Léopold Hertz 준영 22/03/2016


@Juliano Tôi khá bối rối về các mẫu như: mv ~ / Linux /? (Tux * .png) ~ / Linux / New / mv ~ / Linux / + (Tux * .png) ~ / Linux / New / Trước đây , Tôi muốn di chuyển 0-1 Thâp -photo. Sau đó, tôi muốn di chuyển ảnh 1-n Thục. Họ di chuyển mọi nơi. Tại sao? Có thể di chuyển một số lượng hình ảnh cụ thể?
Léo Léopold Hertz 준영 22/03/2016

97

Đặt phần sau vào .bashrc của bạn

shopt -s extglob

Nó mở rộng regexes. Sau đó, bạn có thể di chuyển tất cả các tệp ngoại trừ một

mv !(fileOne) ~/path/newFolder

Các ngoại lệ liên quan đến các lệnh khác

Lưu ý rằng, trong các thư mục sao chép, đèn flash phía trước không thể được sử dụng trong tên như được chú ý trong luồng Tại sao extglob ngoại trừ phá vỡ ngoại trừ điều kiện? :

cp -r !(Backups.backupdb) /home/masi/Documents/

Vì vậy, đã Backups.backupdb/sai ở đây trước khi phủ định và tôi sẽ không sử dụng nó trong các thư mục di chuyển vì nguy cơ sử dụng sai sau đó ảm đạm với các lệnh khác và có thể có các ngoại lệ khác.


3
Đây thực sự là câu trả lời chính xác. Của tôi đã bị dẹp sai; may mắn là tôi đã sử dụng nó trong một thư mục chỉ có vài tập tin. Dưới đây là thông tin thêm về phương pháp mà Masi hiển thị: wiki.bash-hackers.org/syntax/potype Chuyển đến "Ngôn ngữ mẫu mở rộng" và bạn sẽ tìm thấy thêm thông tin về điều này. Cảm ơn @ paul-whittaker đã chỉ ra vấn đề.
mimoralea

Đây là một câu trả lời cũ nhưng nó vẫn còn hiệu lực. Tôi đang sử dụng Ubuntu 18 và extglob dường như được bật theo mặc định (tôi đã không mua nó). Tôi đã sử dụng lệnh sau để di chuyển tất cả các tệp trong thư mục hiện tại vào kho lưu trữ cũng nằm trong thư mục này, KHÔNG bao gồm bất kỳ thư mục lưu trữ nào khác: mv !(arc*) archive_190629b
TonyG

70

Tôi sẽ đi theo cách tìm & xargs truyền thống:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1làm cho nó không tìm kiếm đệ quy. Nếu bạn chỉ quan tâm đến các tập tin, bạn có thể nói -type f. -mindepth 1làm cho nó không bao gồm ~/Linux/Oldchính đường dẫn vào kết quả. Hoạt động với bất kỳ tên tệp nào, kể cả với những tên chứa dòng mới được nhúng.

Một nhận xét lưu ý rằng -ttùy chọn mv là một phần mở rộng GNU. Đối với các hệ thống không có nó

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
Nâng cao vì nó khuyến khích học một công cụ mạnh mẽ, tìm. Lưu ý, đối với các tệp có khoảng trắng sẽ không hoạt động. Xem xét "find -print0 | xargs -0" hoặc nếu không thì xargs: "find [những gì bạn đã nói] -exec mv -t {} ~ / Linux / New \;"
JasonSmith

Nếu lệnh mv của bạn không có tùy chọn -t, thì hãy sử dụng "find ... -exec mv {} Linux / New \;" hoặc "tìm ... | xargs -I {} mv {} Linux / Mới". Tùy chọn -t dường như là một phần mở rộng GNU, phù hợp với Linux, nhưng có lẽ không phải ở nơi nào khác.
Rob Kennedy

jhs, oh tôi thất bại. tôi bằng cách nào đó nghĩ rằng xargs tách ra ở dòng mới nhưng không phải ở không gian. có vẻ như tôi đã nhầm lẫn nó với "đọc" :) tôi sẽ sửa nó
Johannes Schaub - litb

Cảm ơn tuyệt vời cho lời khuyên tuyệt vời! Tôi sẽ chọn sth vì nó nhắm mục tiêu câu hỏi. Tuy nhiên, tôi có thể cảm nhận được sự hữu ích của các lệnh của bạn sau này, vì vậy tôi phải chọn cách "tìm và xargs". Nó chỉ là đá. Cảm ơn :)
Léo Léopold Hertz 준영

Cách phức tạp. Câu trả lời của Masi đầy đủ hơn, dễ dàng hơn và chính xác hơn
user637338

30

Một cách nhanh chóng là sửa đổi tên tệp tux để lệnh di chuyển của bạn không khớp.

Ví dụ:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

không sử dụng " . ", vì điều đó sẽ chỉ di chuyển các tệp có dấu "." trong tên Chỉ cần "*" là đủ.
Juliano

1
Nếu bạn thay đổi nó thành * nó cũng sẽ xóa tệp đã đổi tên của bạn.
John T

6
@ John T: Không, * global không khớp với các tệp bắt đầu bằng dấu chấm.
Bill Karwin

Đây là câu trả lời tốt nhất cho đến nay. Không cần phải thay đổi hoặc bình luận câu trả lời này. 100 điểm. Cảm ơn rất nhiều. Làm tốt!
Steve K

23

Tôi nghĩ rằng cách dễ nhất để làm là với backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Biên tập:

Thay vào đó, sử dụng dấu gạch chéo ngược với ls để tránh sử dụng nó với bí danh, tức là phần lớn ls được đặt bí danh là ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Cảm ơn @Arnold Roa


1
Bạn có thể vui lòng giải thích tại sao bạn sử dụng grep -vở đó?
Léo Léopold Hertz

1
-v tùy chọn trong grep không bao gồm kết quả, nó giống như lấy tất cả mọi thứ ngoại trừ Tux.png
Rohail Abbas

1
Điều này chắc chắn là trực quan, nhưng câu trả lời ở trên là tốt hơn. Ví dụ: nếu bạn đang viết một tập lệnh, điều này sẽ yêu cầu bạn phải ở đúng thư mục ..
nJGL

@nJGL Chúng tôi cũng có thể đưa ra đường dẫn tuyệt đối ở đây, tôi đã sử dụng homedirectory (~) vì câu hỏi đã có
Rohail Abbas

@RohailAbas Hội chợ đủ. ✌️
nJGL

14

Đối với bash, câu trả lời sth là chính xác. Đây là cú pháp zsh (shell of sự lựa chọn của tôi):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Yêu cầu EXTENDED_GLOBtùy chọn shell được đặt.


3
Nếu chúng ta muốn loại trừ hai tệp thì sao?
mở

13

Tôi thấy điều này an toàn hơn một chút và dễ dàng hơn để dựa vào các động tác đơn giản loại trừ các tệp hoặc thư mục nhất định.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

Đây là giải pháp tốt nhất cho Busybox / ASH
Stuart Cardall

1
Điều này làm việc cho tôi trong trường hợp tôi phải di chuyển tất cả các tệp ngoại trừ một vài thư mục sang thư mục khác
Umar Hayat

Các -ltùy chọn để lssẽ bao gồm rất nhiều thông tin không liên quan trên dòng lệnh và kết quả là thất bại của lệnh mv.
jdhao

5

Dưới đây không phải là một phương pháp được đảm bảo 100% và hoàn toàn không nên thử kịch bản. Nhưng một số lần nó là đủ tốt để sử dụng vỏ tương tác nhanh chóng. Một tập tin toàn cầu như

[abc]*

(sẽ khớp với tất cả các tệp có tên bắt đầu bằng a, b hoặc c) có thể được phủ định bằng cách chèn ký tự "^" trước, nghĩa là

[^abc]*

Đôi khi tôi sử dụng điều này để không khớp với thư mục "mất + tìm thấy", ví dụ như:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Tất nhiên nếu có các tệp khác bắt đầu bằng l thì tôi phải xử lý chúng sau đó.


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Lệnh find liệt kê tất cả các tệp thông thường và lệnh fgrep lọc ra bất kỳ tux.png nào. Các backticks nói với mv để di chuyển danh sách tập tin kết quả.


4
Không bao giờ, bao giờ, đánh giá tìm làm đối số cho một lệnh khác. Những điều tồi tệ sẽ xảy ra. Bạn có thể vừa tạo ra một lỗ hổng. Luôn sử dụng find -print0 | xargs -0 xây dựng hoặc tìm -exec.
Juliano

3

Làm thế nào về việc bạn di chuyển mọi thứ trong thư mục và sau đó chỉ cần di chuyển trở lại?

Tôi không thể nghĩ ra bất kỳ cú pháp shell nào để nói "tất cả mọi thứ trừ ...".


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
Lệnh này dường như thiếu một phần và không hoạt động trong máy tính của tôi. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/hoạt động thay thế.
Kinda Chen

3

Làm thế nào về:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

Bạn phải ở trong thư mục mặc dù.


3

Người ta có thể bỏ qua grep như thế này:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

1

Điều này có thể đơn giản và dễ nhớ hơn và nó hoạt động với tôi.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

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.