Xóa tất cả các thư mục từ trong thư mục mẹ ngoại trừ một và các hậu duệ của nó


8

Cấu trúc thư mục

Tôi muốn xóa thư mục B và D. Nhưng tôi muốn giữ C và tất cả các tập tin và thư mục con cháu của nó. Lệnh gì để xóa tất cả các thư mục con của thư mục cha ngoại trừ một thư mục và các thư mục con của nó.

Giúp đánh giá cao.


các thư mục mà bạn muốn loại bỏ trống?
Anh Cả Geek


Điều gì về các tập tin nằm trực tiếp trong thư mục mẹ ( Atrong ví dụ của bạn)? Xóa chúng là tốt hay giữ chúng?
Chỉ huy Byte

Điều mà Byte Commander đang hỏi là, có tập tin nào trong A không? hoặc chỉ thư mục? Bạn có muốn các tập tin thường xuyên trong A bị loại bỏ hoặc chỉ thư mục?
Sergiy Kolodyazhnyy

Câu trả lời:


6

Những gì bạn muốn là lệnh này:

find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;

Bản giới thiệu:

# List what's inside directory we want to remove
$ ls
file1  file2  keepMe/  removeA/  removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)               
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1  file2  keepMe/

Giải trình:

  • find DIRECTORY gọi lệnh find để hoạt động theo TRỰC TIẾP
  • -mindepth 1 : chỉ hoạt động với nội dung của thư mục, tránh chính thư mục đó là cấp 0
  • -maxdepth 1: ngăn chặn giảm dần vào các thư mục con ( rm -rfdù sao cũng là đệ quy, vì vậy chúng ta không cần phải đi xuống các thư mục con để loại bỏ chúng)
  • -type d : chỉ tìm kiếm thư mục
  • -not \( -name "keepMe" \) bỏ qua mục với tên bạn muốn giữ
  • -exec rm -rf {} \; thực hiện loại bỏ trên mỗi mục tìm thấy

Giải thích tuyệt vời. Quá nhiều tổ hợp phím cho tôi mặc dù ...
Anh Cả Geek

1
findlà một người bạn tốt ở đây, nhưng Bash fortestlà những người bạn tốt hơn ...>: - D
Chỉ huy Byte

8

Sử dụng các tính năng toàn cầu mở rộng của bash shell (được bật theo mặc định trong các cài đặt Ubuntu hiện tại), được cung cấp

$ tree A
A
├── B
├── C
│   ├── ac1
│   └── ac2
└── D

5 directories, 0 files

bạn có thể giải quyết mọi thứ ngoại trừ Cvà nội dung của nó bằng biểu thức toàn cầu A/!(C)tức là

$ echo A/!(C)
A/B A/D

Vì vậy, để loại bỏ mọi thứ trừ thư mục Cvà nội dung của nó, bạn chỉ cần sử dụng

rm -rf A/!(C)

rời đi

$ tree A
A
└── C
    ├── ac1
    └── ac2

3 directories, 0 files

Thật tuyệt vời khi biết về tính năng này. Nó hoạt động rất tốt sau khi tôi ssh và chạy thủ công nhưng tôi nhận được `" -bash: dòng 1: lỗi cú pháp gần mã thông báo bất ngờ ('"khi tôi chạy nó từ xa thông qua ssh $VM_ADDRESS "rm -rf $APP_FOLDER/!(node_modules)". Có ý tưởng nào không? Cảm ơn rất nhiều.
Renato Gama

@renatoargh extglobtùy chọn shell chỉ được kích hoạt cho các shell tương tác - không chắc bạn có thể buộc sshphải làm điều đó hay không
Steeldo

5

Một cách dễ dàng là sử dụng thùng rác

bạn có thể cài đặt nó với sudo apt-get install trash-cli

Sau khi cài đặt, bạn có thể điều hướng đến thư mục mẹ A cd /Avà sau đó đưa ra lệnh trash B Dtrong đó B và D là các thư mục bạn muốn xóa (chúng sẽ nằm trong thùng rác cho ổ đĩa mà chúng đang chạy vì vậy nếu bạn mắc lỗi, bạn có thể phục hồi các tập tin)

Đã thử nghiệm theo Ubuntu 16.04 và 14.04


Điều này có thể được đơn giản hóa với một cái gì đó như thế trash ! Cnào?
Sergiy Kolodyazhnyy

@Serg Không trash: cannot trash non existent ! '`
Anh Cả Geek

@Serg và C bị vùi dập ...
Anh Cả Geek

Đã tìm thấy: stackoverflow.com/q/216995/3701431 Nó yêu cầu kích hoạt extglobmặc dù.
Sergiy Kolodyazhnyy

@Serg Tùy thuộc vào công việc trong tay mà có thể khá hữu ích! ;-)
Anh Cả Geek

4

Chỉ cần sử dụng forvòng lặp của Bash và testđể lọc các thư mục mong muốn và rm -rflệnh để xóa đệ quy các thư mục, như thế này:

for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done

Điều này lặp lại trên tất cả các phần tử (tệp và thư mục) bên trong /path/to/parent/và xóa phần tử theo cách đệ quy nếu tên của nó không bằng dir_survive. Nếu thư mục mẹ là thư mục hiện tại, bạn chỉ có thể viết *dưới dạng đường dẫn.

Nếu bạn không chắc chắn và muốn kiểm tra phần tử nào sẽ bị xóa trước mà không thực hiện bất kỳ hành động nào, chỉ cần thay thế rm -rflệnh trong ở trên echovà nó sẽ chỉ xuất ra các ứng cử viên xóa.

Đây là một ví dụ chạy:

$ tree
.
├── dir1
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
├── dir2
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

9 directories, 12 files

$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done

$ tree
.
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

3 directories, 4 files
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.