Làm thế nào để di chuyển tất cả các tập tin từ thư mục hiện tại sang thư mục trên?


133

Làm thế nào để di chuyển tất cả các tập tin từ thư mục hiện tại sang thư mục trên trong linux?

Tôi đã thử một cái gì đó như mv *.*, nhưng nó không hoạt động.


Tôi không có đủ đại diện để thử lại câu hỏi, nhưng tôi có thể đề xuất [linux] [mv] [cwd] [files]hoặc một cái gì đó tương tự không?
Stephan202

Tôi đã thử lại câu hỏi này theo yêu cầu của Stephan202.
eleven81

Câu trả lời:


202

Lệnh bạn đang tìm kiếm là

mv * .[^.]* ..

hoặc (xem bên dưới để biết thêm):

(shopt -s dotglob; mv -- * ..)

Giải thích: mvlệnh di chuyển các tập tin và thư mục. Đối số cuối cùng mvlà đích (trong trường hợp này là thư mục một bước "lên" trong cây, ..). Các đối số trước đó là các tập tin nguồn và thư mục. Dấu hoa thị ( *) là ký tự đại diện khớp với tất cả các tệp không bắt đầu bằng dấu chấm. Các tệp bắt đầu bằng dấu chấm (dotfiles) bị "ẩn". Chúng được kết hợp bằng cách sử dụng mẫu .[^.]*(xem chỉnh sửa bên dưới).

Xem trang hướng dẫn mà tôi đã liên kết để biết thêm thông tin mv.


Tại sao .[^.]*thay vì .*?

Như Chris Johnsen đã chỉ ra một cách chính xác: mô hình .*cũng khớp .... Vì bạn không muốn (và không thể) di chuyển chúng, tốt hơn là sử dụng một mẫu phù hợp với bất kỳ tên tệp nào bắt đầu bằng một dấu chấm trừ hai cái đó . Mẫu .[^.]*này thực hiện đúng như vậy: nó khớp với bất kỳ tên tệp (1) nào bắt đầu bằng dấu chấm (2) theo sau là một ký tự không phải là dấu chấm (3) theo sau là 0 hoặc nhiều ký tự tùy ý.

Như Paggas chỉ ra , chúng tôi cũng phải thêm mẫu .??*để khớp các tệp bắt đầu bằng hai dấu chấm. Xem câu trả lời của anh ấy cho một giải pháp thay thế bằng cách sử dụng find.

Câu trả lời của Arjan đề cập shoptđể tránh tất cả những vấn đề đó với dotfiles. Nhưng sau đó vẫn còn vấn đề với các tập tin bắt đầu bằng dấu gạch ngang. Và nó đòi hỏi ba lệnh. Tuy nhiên, tôi thích ý tưởng này. Tôi đề nghị sử dụng nó như thế này:

(shopt -s dotglob; mv -- * ..)

Điều này thực thi shopttrong một lớp con (do đó không shoptyêu cầu cuộc gọi thứ hai ) và sử dụng --để các tệp bắt đầu bằng dấu gạch ngang sẽ không được hiểu là đối số mv.


7
Việc sử dụng .*có thể khiến mv tạo ra các cảnh báo / lỗi về việc không thể di chuyển .... Bạn có thể thử mv * .[^.]* ..thay thế.
Chris Johnsen

1
@alain: bạn được chào đón và chào mừng đến với trang web! (Nếu (và chỉ nếu) một trong những bài đăng ở đây đã trả lời đầy đủ câu hỏi của bạn, thì bạn có thể đánh dấu nó như vậy. Điều đó sẽ giúp người đăng thêm 15 điểm danh tiếng và cũng cung cấp cho bạn thêm 2 đại diện.)
Stephan202

Tôi thực sự thích giải pháp shopt chạy trong một subshell :)
Paggas

2
Không có hại trong cú pháp *. * - bao gồm .. chỉ nguy hiểm khi được sử dụng với chmod và chown và cờ "recurse", tức là chmod -R hoặc chown -R. Và trong những trường hợp đó, đừng bao giờ gõ chown. * Hoặc chmod. * - chown thư mục trên cùng trong đường dẫn bạn đang tìm kiếm và sử dụng -h (không theo các liên kết tượng trưng). Nhưng, mv .. đơn giản là không làm gì cả nên đừng lo lắng về điều đó.
chris

1
Ba mẫu chính xác là *, .[^.]*..?*. Thứ hai có thể .[!.]*cho vỏ cũ (POSIX). Cũng đọc

42

Câu trả lời ngắn: sử dụng

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Câu trả lời dài:

Lệnh

mv * .* ..

sẽ không hoạt động vì .*có thể phù hợp .... Nhưng lệnh

mv * .[^.]* ..

cũng sẽ không hoạt động, vì .[^.]*sẽ không khớp, ví dụ , ..filename! Thay vào đó, những gì tôi làm là

mv * .[^.] .??* ..

mà sẽ phù hợp với tất cả mọi thứ ngoại trừ .... *sẽ khớp với tất cả mọi thứ không bắt đầu bằng a ., .[^.]sẽ khớp với tất cả tên tệp 2 ký tự bắt đầu bằng dấu chấm trừ ...??*sẽ khớp với tất cả tên tệp bắt đầu bằng dấu chấm có ít nhất 3 ký tự.

Tốt hơn nữa, bạn có thể sử dụng

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

trong đó tránh các hack toàn cầu xấu xí trong mv * .[^.] .??* ..!


1
Ngoài ra, tôi quên lưu ý tầm quan trọng của - để lệnh hoạt động chính xác với tên tệp bắt đầu bằng dấu gạch ngang. Tôi đã bao gồm - trong câu trả lời tìm thấy của tôi mặc dù. Một câu trả lời đầy đủ hơn bằng cách sử dụng globs là "mv - *. [^.]. ?? * ..".
Paggas

+1: Tôi đã quay lại để thêm ..?*vào nhận xét của mình và bạn đã quan tâm đến nó.
Chris Johnsen

1
Điều gì có thể có thể sai khi cố gắng để mv ..? Nó chỉ đơn giản là không làm gì và không thể làm gì. Có những lệnh khác mà nó có thể làm một cái gì đó (chmod và chown) nhưng mv và rm đơn giản là không làm gì cả. hoặc ..
chris

1
Điều này mang lại cho mv: tùy chọn bất hợp pháp - t
pal4life

1
Bono, dấu gạch ngang kép bảo mvngừng tìm kiếm bất kỳ tùy chọn lệnh nào nữa. Niềng răng là một tên tệp kết quả. Dấu cộng cho biết thay vì chạy exec trên mỗi kết quả (ví dụ: mỗi tên tệp), hãy đặt càng nhiều kết quả trong một lần thực thi càng tốt. Để hoàn thiện, việc thông báo -t..di chuyển đích đến để di chuyển tất cả các tệp này sang.
isuldor

14

Để hoàn thiện, người ta cũng có thể yêu cầu shell Bash bao gồm các tệp ẩn, sử dụng shopt:

shopt -s dotglob
mv -- * ..
shopt -u dotglob

+1. Sạch sẽ hơn nhiều. Tôi nghĩ rằng một sự cải thiện nhỏ là theo thứ tự, mặc dù. Xem bản cập nhật cho câu trả lời của tôi.
Stephan202

8

Các mv thiếu chức năng di chuyển các tập tin ẩn khi sử dụng *- vậy tại sao không sử dụng bản sao thay thế?

cp -rf . ..

rm -rf *

Không cần phải đi vào các giải pháp phức tạp của dotglobbing và sử dụng các lệnh find.


Cảnh báo Nếu bạn đang di chuyển trong cùng một hệ thống tệp , trong phần lớn nhất của các trường hợp bạn không thực sự sao chép các tệp mà chỉ cập nhật các mục trong thư mục mà không di chuyển các nút inode hoặc tệp. Xem thậm chí [1 ]. Với một cprmthay vào đó bạn đang thực sự sao chép tất cả.
Hastur

6
rsync -a --remove-source-files . ..

rsync là một công cụ sao chép tệp cực kỳ mạnh mẽ, thường được sử dụng để thực hiện sao lưu từ xa và gương hiệu quả.

Với lệnh trên, chúng tôi đang yêu rsynccầu sao chép nội dung .vào..

Công tắc -acho phép đệ quy vào các .thư mục con và cho phép một số tùy chọn phổ biến khác.

Công tắc --remove-source-filesyêu cầu rsync xóa các tệp nguồn sau khi sao chép thành công, tức là nó làm cho rsync hoạt động tương tự như mvlệnh.


1
Một chút giải thích sẽ tốt đẹp.
ChrisF

Chắc chắn, hy vọng nó rõ ràng hơn bây giờ.
mrucci

Lưu ý rằng --remove-source-filessẽ không loại bỏ (đồng bộ hóa) thư mục.
Dennis

Giải pháp tốt đẹp, được chấp nhận cho tôi -bash: /bin/mv: Argument list too longlỗi. Điều này làm việc như sự quyến rũ.
dùng

2

Cuối cùng, việc thử mv .sẽ thất bại vì mv sẽ không thể hủy liên kết thư mục mà bạn hiện đang ở. Bạn có thể mv * ..di chuyển các tệp trong cwd.


2
mv * .??* ../.

*được tất cả các tập tin không chấm. .??*được tất cả. các tệp dài ít nhất ba byte, hoạt động cho tất cả các tệp hợp pháp. Bất cứ điều gì còn lại bạn có thể muốn rmhơn là mvdù sao.

Việc ../.này không mang lại bất kỳ lợi ích trực tiếp nào ..nhưng khi thực hiện chuyển đến thư mục thì đó là một thói quen rất tốt, bởi vì nó sẽ thất bại, như bạn muốn, nếu có gì đó không đúng với đường dẫn. Ví dụ, mv xyz bletchnơi bạn nghĩ bletch là một thư mục, có thể được làm chắc chắn hơn với mv xyz bletch/..


2
Bạn có thể thêm .[^.]để có được các tập tin bìa như .a.
Chris Johnsen

Không có sự khác biệt giữa ../ và ../. Vì vậy, tôi sẽ không bận tâm gõ. sau khi chém. Ngoài ra, trong trường hợp mv và rm, không có hại bao gồm. và .. trong danh sách, tức là không có gì đáng sợ hoặc sai với mv *. * / path / to / file /, giống như rm. hoặc thậm chí -rf. không làm gì cả
chris

2

Lệnh thu nhỏ này hoạt động trên hầu hết các shell hiện đại:

\mv -- {,.{[^.],??}}* ..

Mặt khác được đề cập là một giải pháp di động:

\mv -- * .[^.] .??* ..

Đặc trưng:

  1. \ ngăn bí danh thay đổi mv không mong muốn.

  2. - ngăn tên tệp chứa các dấu gạch nối hàng đầu (-xyz) khỏi bị hiểu là đối số dòng lệnh.

  3. . [^.] khớp với tất cả tên tệp của hai ký tự bắt đầu bằng. ngoại trừ ..

  4. . ?? * khớp với tất cả tên tệp khác từ ba ký tự trở lên.

Triển khai ngây thơ:

  1. Sau đây bỏ qua các tên tệp UNIX ẩn, những tên bắt đầu bằng. (.bashrc).

    mv * ..
    
  2. Các kết quả khớp sau đây .. mà đệ quy cố gắng di chuyển mọi thư mục cuối cùng trở lại / vào .. của thư mục làm việc hiện tại ($ PWD hoặc pwd). Không bao giờ sử dụng.

    mv .* ..
    

2

Sử dụng mô hình chính xác * .[!.] .??*hơn so với * .[^.] .??*trước đây cũng sẽ hoạt động với các vỏ cũ hơn như ksh88:

mv -- * .[!.] .??* ..
  • -- ngăn chặn sự cố khi bạn có tên tệp bắt đầu bằng -
  • * khớp với tất cả các tên tệp không bắt đầu bằng .
  • không có một tên tệp ký tự nào bắt đầu bằng một tên .mà bạn có thể / nên di chuyển
  • .[!.] khớp với tất cả hai tên tệp ký tự bắt đầu bằng .
  • .??* khớp với cả ba tên tệp ký tự (hoặc dài hơn) bắt đầu bằng một .

Với ksh88, mẫu tên tệp .[^.]trên thực tế sẽ khớp với tên tệp ..(luôn tồn tại) và .^(có lẽ không tồn tại), có tác động ngược lại với những gì mong muốn.


0

Tìm và grep làm việc quá. Kiểu cấu trúc này có thể hữu ích nếu bạn muốn chọn các tệp theo tiêu chí phức tạp hơn bằng cách sửa đổi find và egrep.

find -maxdepth 1 | egrep '^./.'         # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..

0

Tôi nghĩ rằng giải pháp đơn giản nhất để di chuyển tất cả các tập tin vào thư mục mẹ của nó. sẽ là

mv "`ls`" ../

hoặc, nếu có các tập tin / thư mục ẩn

sử dụng:

mv "`ls -a`" ../ 2>/dev/null

Ngoài ra, giả sử bạn muốn di chuyển nội dung của một số thư mục sang một trong các thư mục nội bộ của nó (giả sử)

sử dụng:

mv "`ls -a`" /tony 2>/dev/null

Ghi chú:

"`ls -a`" 

Để di chuyển các tập tin có không gian trong đó.

2>/dev/null

Là để chặn cảnh báo / lỗi vì ls -acũng sẽ in ...thư mục và bạn không thể di chuyển hoặc sao chép chúng. Vì vậy, đối với các thư mục đó, nó sẽ hiển thị lỗi (nếu chúng tôi không sử dụng 2> / dev / null) rằng nó không thể di chuyển chúng và phần còn lại sẽ được di chuyển khá thoải mái.

Tốt nhất nên tránh ls -anếu không có tập tin ẩn và chỉ sử dụng ls.


Bạn đã thử những gì sẽ xảy ra khi bạn chạy mv $(ls -a)? Điều đó sẽ nhấn vào thư mục hiện tại và thư mục bên dưới nó, vì ls -acũng sẽ xuất ra ...
Sami Laine

Cảm ơn, @SamiLaine vì gợi ý tôi đã thực hiện chỉnh sửa. Nhưng mv ls -a ../cũng sẽ hoạt động theo nhu cầu, Có, nó sẽ hiển thị các lỗi như tôi đã đề cập ở trên nhưng ngoài ra nó sẽ di chuyển các thư mục / tệp cần thiết vào thư mục gốc.
Bohhat Kumar Singh

Điều này sẽ không làm việc cho các tập tin với không gian.
kenorb

@kenorb bạn cần trích dẫn gấp đôi lslệnh để di chuyển tệp có dấu cách. Tôi đã thực hiện các thay đổi cần thiết. Cảm ơn đã chỉ ra.
Mitchhat Kumar Singh
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.