2011-02-28 54 views
54

Tôi có một tập tin văn bản dài với danh sách các mặt nạ tập tin tôi muốn xóaUnix: Làm thế nào để xóa các tập tin được liệt kê trong một tập tin

Ví dụ:

/tmp/aaa.jpg 
/var/www1/* 
/var/www/qwerty.php 

Tôi cần xóa chúng. Đã thử rm ` cat 1.txt ` và nó cho biết danh sách quá dài.

Tìm thấy lệnh này, nhưng khi tôi kiểm tra các thư mục từ danh sách, một số trong số chúng vẫn có các tệp xargs rm <1.txt Cuộc gọi rm thủ công sẽ xóa các tệp khỏi các thư mục đó, vì vậy không có vấn đề với quyền.

+4

Mặc dù đã sáu năm sau: Bạn có nhận được một trong những câu trả lời không?Điều này sẽ đánh dấu câu hỏi là đã được giải quyết và cũng giúp người dùng khác. – MERose

+0

@ Alexander: bạn nên có sự quyết định và chấp nhận câu trả lời ưa thích đã .. không chỉ leech trên diễn đàn này. Tôi thấy bạn đã trực tuyến hôm qua – Marius

Trả lời

11

xargs -I{} sh -c 'rm {}' < 1.txt nên làm những gì bạn muốn. Hãy cẩn thận với lệnh này vì một mục nhập sai trong tệp đó có thể gây ra nhiều rắc rối.

Câu trả lời này đã được chỉnh sửa sau khi @tdavies chỉ ra rằng bản gốc không mở rộng vỏ.

+0

Cảm ơn bạn, nhưng không cần phải xóa thư mục, chỉ các tệp – Alexander

+1

Bóng đèn sẽ không được mở rộng vì chúng không bao giờ bị 'nhìn thấy' bởi vỏ. – tgdavies

+0

@tdavies wow - bạn nói đúng. Lệnh này (mặc dù một chút xấu xí) sẽ hoạt động: 'xargs -I {} sh -c 'rm {}' <1.txt' –

75

Đây không phải là rất hiệu quả, nhưng sẽ có tác dụng nếu bạn cần mẫu glob (như trong/var/www/*)

for f in $(cat 1.txt) ; do 
    rm "$f" 
done 

Nếu bạn không có bất kỳ mô hình và là đường dẫn của bạn chắc chắn trong tập tin không chứa khoảng trắng hoặc những điều kỳ lạ khác, bạn có thể sử dụng xargs như vậy:

xargs rm < 1.txt 
9

bạn có thể sử dụng một lớp lót:

cat 1.txt | xargs echo rm | sh 

Việc mở rộng vỏ nào nhưng thực thi số rm số lần tối thiểu.

+0

Miễn là mọi mở rộng không phải là quá dài? –

+1

Đúng, một glob có thể tạo ra một danh sách đối số quá dài - bạn có thể thêm đối số '-n ' vào 'xargs' để giảm số đối số được truyền cho mỗi rm, nhưng điều đó sẽ vẫn không bảo vệ bạn khỏi duy nhất glob vượt quá giới hạn. – tgdavies

0

đây bạn có thể sử dụng thiết lập các thư mục từ deletelist.txt khi tránh một số mẫu cũng

foreach f (cat deletelist.txt) 
    rm -rf ls | egrep -v "needthisfile|*.cpp|*.h" 
end 
32

Giả sử rằng danh sách các tập tin có trong tập tin 1.txt, sau đó làm:

xargs rm -r <1.txt 

Tùy chọn -r làm đệ quy vào bất kỳ thư mục nào có tên trong 1.txt.

Nếu bất kỳ tập tin là chỉ đọc, sử dụng tùy chọn -f để buộc các xóa:

xargs rm -rf <1.txt 

Hãy thận trọng với đầu vào bất kỳ công cụ mà không xóa bỏ chương trình. Thực hiện nhất định rằng các tệp được đặt tên trong tệp đầu vào thực sự bị xóa. Đặc biệt cẩn thận về các lỗi chính tả đơn giản. Ví dụ, nếu bạn nhập một khoảng trống giữa một tập tin và hậu tố của nó, nó sẽ xuất hiện hai tên tập tin riêng biệt:

file .txt 

thực sự là hai tập tin riêng biệt: file.txt.

Điều này có vẻ không quá nguy hiểm, nhưng nếu typo là một cái gì đó như thế này:

myoldfiles * 

Sau đó, thay vì xóa tất cả các file bắt đầu với myoldfiles, bạn sẽ kết thúc xóa myoldfilestất cả phi -dot-files và thư mục trong thư mục hiện tại. Có lẽ không phải những gì bạn muốn.

+0

"myoldfiles /" hoặc "/ tmp" thậm chí còn tai hại hơn với -rf. Lưu ý ký tự dấu cách bên cạnh "/". – Ray

9

Sử dụng này:

while read file ; do rm "$file" ; done < delete.list 

Nếu bạn cần mở rộng glob bạn có thể bỏ qua trích dẫn $file:

while read file ; do rm $file ; done < delete.list 

Nhưng được cảnh báo rằng tên tệp có thể chứa "có vấn đề" nội dung và tôi sẽ sử dụng không thể viện chứng phiên bản. Hãy tưởng tượng mẫu đó trong tệp

-rf * 

Thao tác này sẽ xóa mọi thứ đệ quy trong thư mục hiện tại! Tôi sẽ khuyến khích bạn chuẩn bị danh sách xóa theo cách mà các mẫu glob không cần nữa, và sau đó sử dụng trích dẫn như trong ví dụ đầu tiên của tôi.

1

Trong trường hợp đặc biệt này, do sự nguy hiểm được trích dẫn trong câu trả lời khác, tôi sẽ

  1. Chỉnh sửa trong ví dụ Vim và :%s/\s/\\\0/g, thoát tất cả ký tự khoảng trắng bằng dấu gạch chéo ngược.

  2. Sau đó :%s/^/rm -rf /, hãy thêm lệnh trước. Với -r bạn không phải lo lắng về việc có các thư mục được liệt kê sau các tệp có trong đó và với -f nó sẽ không khiếu nại do thiếu tệp hoặc mục trùng lặp.

  3. Chạy tất cả các lệnh: $ source 1.txt

1

Dưới đây là một ví dụ vòng lặp. Cái này cũng chứa một 'lệnh if-' như một ví dụ về kiểm tra để xem nếu mục là một 'tập tin' (hoặc 'thư mục' ví dụ):

for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done 
6

Bạn nên sử dụng '\ n' cho xác định ký tự dòng mới làm dấu phân tách.

xargs -d '\n' rm < 1.txt 

Hãy cẩn thận với -rf vì nó có thể xóa những gì bạn không muốn nếu 1.txt chứa đường dẫn có dấu cách. Đó là lý do tại sao đường phân cách mới an toàn hơn một chút.

+1

Trên OS X, điều này giúp tôi 'xargs: tùy chọn bất hợp pháp - d' – waldyrious

+0

Điểm tốt. Có vẻ như không có tùy chọn nào khác ngoài '-0' trên OS X. – Ray

+2

' xargs -I_ rm _' cũng hoạt động trong OS X :) xem http://stackoverflow.com/a/39335402/266309 – waldyrious

0

Điều này sẽ cho phép tên tệp có không gian (ví dụ về bản sao).

# Select files of interest, here, only text files for ex. 
find -type f -exec file {} \; > findresult.txt 
grep ": ASCII text$" findresult.txt > textfiles.txt 
# leave only the path to the file removing suffix and prefix 
sed -i -e 's/:.*$//' textfiles.txt 
sed -i -e 's/\.\///' textfiles.txt 

#write a script that deletes the files in textfiles.txt 
IFS_backup=$IFS 
IFS=$(echo "\n\b") 
for f in $(cat textfiles.txt); 
do 
rm "$f"; 
done 
IFS=$IFS_backup 

# save script as "some.sh" and run: sh some.sh 
2

cat 1.txt | xargs rm -f | bash Chạy lệnh sẽ thực hiện các thao tác sau chỉ cho tệp.

cat 1.txt | xargs rm -rf | bash Chạy lệnh sẽ thực hiện hành vi đệ quy sau đây.

Các vấn đề liên quan