Làm cách nào để loại trừ một số tệp khỏi cơ chế mở rộng tên tệp trong bash?


14

Tôi có thư mục hệ thống tập tin Ubuntu trong thư mục gốc và tôi vô tình sao chép hàng trăm tệp vào thư mục gốc.

Tôi trực giác cố gắng loại bỏ các tập tin sao chép bằng cách loại trừ hệ thống tập tin như

rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.

bu nó không hoạt động. Cách thích hợp để loại trừ một số thư mục trong khi xóa toàn bộ là gì?

EDIT: Không bao giờ thử bất kỳ lệnh nào ở đây mà không biết phải làm gì!


1
Bạn đang sử dụng vỏ gì? Tên tệp globalbing phụ thuộc vào vỏ khi thực hiện các công cụ ưa thích như thế.
Kusalananda

2
Không phải là một câu trả lời, nhưng tôi sẽ sử dụng ví dụ mc. Chọn mọi thứ với *, sau đó bỏ chọn các tệp cụ thể bằng -hoặc Insertkhóa.
pbm

1
Bạn có thể giải thích 'mc' là gì không?
MikeP

@Kusalananda đó là/bin/bash
kenn

3
@MikeP: mclà Midnight Commander, một mô phỏng rất hữu ích của Norton Commander. Nó chạy trong một thiết bị đầu cuối. (Cả Midnight Commander và Norton Commander là những ví dụ về cái được gọi là trình quản lý tệp chính thống .)
AlexP

Câu trả lời:


21

Vì bạn đang sử dụng bash:

shopt -s extglob
echo rm -rf ./!(bin|sbin|usr|...)

Tôi khuyên bạn nên thêm echovào đầu dòng lệnh khi bạn đang chạy thứ gì đó có khả năng làm nổ tung toàn bộ hệ thống. Hủy bỏ nó nếu bạn hài lòng với kết quả.

Lưu ý: Lệnh trên sẽ không xóa các tệp ẩn (những tên bắt đầu bằng dấu chấm). Nếu bạn cũng muốn loại bỏ chúng thì hãy kích hoạt dotglobtùy chọn:

shopt -s dotglob

Tôi đã sử dụng nó để dọn sạch hệ thống tập tin thành công. Lúc đầu tôi đã thử nó trong một thư mục. Tôi cũng đã thử rm -rf ./!(bin,sbin,..)phân tách dấu phẩy, nhưng nó xóa tất cả các thư mục.
kenn

!(...)Cú pháp đó là gì? Từ ví dụ tôi nghĩ theo trực giác ls ./!(*/)sẽ chỉ liệt kê các tệp, nhưng nó không hoạt động theo cách đó.
giusti

@giusti Cú pháp này là khớp mẫu mở rộng trong cơ chế mở rộng tên tệp - bạn sẽ tìm thấy mô tả của nó trong hướng dẫn bash trong chương Mở rộng tên đường dẫn. Nó không thể được sử dụng để loại trừ các loại tệp, chỉ tên, giống như với dấu sao *hoặc các khối khác.
jimmij

12

Lệnh này sẽ hiển thị tất cả các thư mục không trong /:

find / -maxdepth 1 -type f

Một khi bạn đã thực hiện hoàn toàn chắc chắn không tạo các file đang có mà bạn muốn giữ lại, bạn có thể sử dụng:

find / -maxdepth 1 -type f -delete

An toàn hơn, sẽ là di chuyển chúng đi nơi khác để đảm bảo bạn không xóa thứ gì bạn muốn bảo quản:

mkdir /root/preserve
find / -maxdepth 1 -type f -exec mv -- "{}" /root/preserve/\;

Nếu, ngoài các tệp, bạn cũng có các thư mục mà bạn đã thêm vào thư mục gốc của hệ thống tệp, điều này có thể được tự động hóa bằng cách loại trừ các thư mục LSB khỏi tự động mvhoặc rm, nhưng thành thật mà nói, vì chúng tôi đang xử lý các thứ trong thanh lọc gốc của hệ thống tập tin, tôi thực sự khuyên bạn nên xem xét thực hiện thủ công nếu hoàn toàn khả thi.

Nếu điều này là không khả thi, một cái gì đó như thế này có thể thực hiện thủ thuật:

#!/bin/bash
declare -a excludes
for item in root sys 'lost+found' mnt home proc etc opt boot lib lib64 libx32 sbin media srv dev var usr bin tmp run; do
    excludes+=("$item")
done
if ! [[ -d /root/preserve ]]; then
    mkdir -p /root/preserve
fi
IFS="\n"
for item in find / -type d -maxdepth 1; do
    really=true
    for exclude in ${excludes[@]}; do
        if [[ "$exclude" == "${item#/}" ]]; then
            really=false
        fi
    done
    if [[ "true" == "$really" ]]; then
        mv -- "$item" /root/preserve/
    fi
done

Khi bạn đã vượt qua bài kiểm tra la hét (tức là hệ thống của bạn vẫn chạy và bạn không hét lên vì tức giận), bạn có thể xóa nội dung của /root/preserve/.

Lưu ý quan trọng: Dù bạn làm gì, thậm chí đừng nghĩ về việc chạy bất kỳ hoán vị nào rm -fr [ANYTHING GOES HERE] /.


giải pháp của bạn chỉ xóa các tập tin nhưng có những thư mục xung quanh quá.
kenn

1
Một lần quá nhiều, tôi đã nghe thấy những tiếng thét thất vọng từ một mục tiêu kém rm. Giống như một kịch bản rm -fr $somepath/với somepathchưa được khởi tạo trong đó. Tôi có thể đã đi xa hơn trong việc thể hiện mức độ nghiêm trọng của nó, nhưng đã chọn cách thân thiện với gia đình trong lời khuyên của tôi.
DopeGhoti

3

Điều này sẽ hoàn thành công việc (mặc dù không giống như cách OP yêu cầu):

ls -1 >1.txt
pico 1.txt 

xóa tất cả các tập tin / thư mục bạn muốn giữ

xargs rm < 1.txt

Nếu tất cả các tệp của bạn có cùng định dạng tên, ngày hoặc một cái gì đó khác, thì có các phương pháp khác.

Tôi sẽ xem xét các nút - và xem liệu chúng có tuần tự thông qua ls -i | sort và nếu có, thì các tệp mới sẽ có các nút lớn hơn. Sau đó sử dụng cùng loại quy trình như trên ...

ls -iF1 | sort |cut -c10- | grep -vE "\/|\@" >i.txt   #This part removes entries that are not regular files, such as directories and links.  
pico i.txt
xargs rm < i.txt

trong lệnh cắt ở trên, trước tiên hãy kiểm tra danh sách inodes của bạn để đảm bảo rằng đó là số tiền phù hợp.

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.