Xóa các tệp có khoảng trắng trong tên của chúng


10

Tôi đang cố gắng xóa tất cả các tập tin với một khoảng trắng trong tên của họ. Tôi đang sử dụng lệnh sau. Nhưng nó đang cho tôi một lỗi

Chỉ huy : ls | egrep '. ' | xargs rm

Ở đây nếu tôi chỉ sử dụng ls | egrep '. 'lệnh thì nó sẽ cho tôi tất cả tên tệp có khoảng trắng trong tên tệp. Nhưng khi tôi cố gắng chuyển đầu ra cho rm, tất cả các khoảng trắng (dẫn hoặc theo dõi) sẽ bị xóa. Vì vậy, lệnh của tôi không được thực hiện đúng.

Bất kỳ con trỏ về làm thế nào để xóa các tập tin có ít nhất một không gian trong tên của họ?

Câu trả lời:


29

Bạn có thể sử dụng tiêu chuẩn toàn cầu trên rmlệnh:

rm -- *\ *

Điều này sẽ xóa bất kỳ tập tin có tên chứa một khoảng trắng; không gian được thoát ra để cái vỏ không diễn giải nó như một dấu phân cách. Việc thêm --sẽ tránh các vấn đề với tên tệp bắt đầu bằng dấu gạch ngang (chúng sẽ không được hiểu là đối số bởi rm).

Nếu bạn muốn xác nhận từng tệp trước khi xóa, hãy thêm -itùy chọn:

rm -i -- *\ *

4
Bạn sẽ DEFINITELY muốn chạy cái này qua cái echođầu tiên, để bảo vệ khỏi lỗi chính tả. Thêm echoở phía trước và nó sẽ in ra tất cả các tệp mà nó sẽ xóa.
Đi xe đạp

1
Anuj, lý do tại sao điều này có nhiều sự ủng hộ nhất là bởi vì mặc dù findrất mạnh mẽ, đôi khi bạn không cần phải giết gà bằng súng máy. Các quản trị viên UNIX thường không dùng đến find(ví dụ) "xóa tất cả các tệp bắt đầu bằng chữ A" ... một cách đơn giản rm A*. Tương tự như vậy để loại bỏ các tập tin có chứa khoảng trắng, rm có thể thực hiện công việc. Nói cách khác, đừng để bị lừa bởi vì không gian là vô hình và được đối xử đặc biệt bởi vỏ. Đơn giản là thoát khỏi nó, như Stephen Kitt đã làm, và bạn có thể nghĩ về nó giống như bất kỳ nhân vật nào khác.
Mike S

14

Tôi sẽ tránh phân tích cú pháp lsđầu ra

Tại sao không :

find . -type f -name '* *' -delete

Không có vấn đề với rm:-).

Mặc dù điều này là đệ quy và sẽ xóa tất cả các tệp có không gian trong thư mục hiện tại và các thư mục lồng nhau, như đã đề cập trong các bình luận.


4
(1) bạn có thể sử dụng -name '* *'thay vì regex; và (2) bạn có thể sử dụng -print0 | xargs -0 rm -iđể giải quyết mối quan tâm của @ StephenKitt.
Kevin

1
Không cần xargs. Chỉ cần sử dụng-exec rm -i '{}' +
R .. GitHub DỪNG GIÚP ICE

1
@Mhmd Nó có nhiều cạm bẫy hơn so với máy chơi game 8 bit. mywiki.wooledge.org/ParsingLs
Daenyth

1
Nếu bạn muốn tránh các thư mục con, hãy sử dụng find . -maxdepth 1 -name '* *' -delete.
Mikkel

1
@BenjaminW. đã sửa ?
solsTiCe

6

Nhìn vào cái tên Giả sử "tập tin lạ" này

Giải pháp một

rm strange\ file

giải pháp hai

rm "strange file"

giải pháp ba

ls -i "strange file"

bạn thấy inode rồi

find . -inum "numberoofinode" -exec rm {} \;

Trong trường hợp tên tập tin rất lạ như

!-filename or --filename

sử dụng

rm ./'!-filename'

4

Từ man xargs

xargs đọc các mục từ đầu vào tiêu chuẩn, được phân cách bằng khoảng trắng (có thể được bảo vệ bằng dấu ngoặc kép hoặc dấu ngoặc đơn hoặc dấu gạch chéo ngược) hoặc dòng mới và thực thi lệnh (mặc định là / bin / echo) một hoặc nhiều lần với bất kỳ đối số ban đầu nào được theo sau bởi các mục được đọc từ đầu vào tiêu chuẩn. Các dòng trống trên đầu vào tiêu chuẩn được bỏ qua.

Chúng tôi có thể (chủ yếu) sửa lỗi lệnh ban đầu của bạn bằng cách thay đổi dấu phân cách xargs thành một dòng mới:

ls | egrep '. ' | xargs -d '\n' rm (đừng làm điều này ... đọc tiếp)

Nhưng nếu tên tệp chứa một dòng mới thì sao?

touch "filename with blanks and newline"

tên tệp Unix có thể chứa khoảng trắng và dòng mới , hành vi mặc định này thường có vấn đề; tên tệp chứa khoảng trống và / hoặc dòng mới được xargs xử lý không chính xác. Trong những tình huống này, tốt hơn là sử dụng tùy chọn -0 , để ngăn chặn các vấn đề như vậy.

ls thực sự là một công cụ để con người tiêu thụ trực tiếp , thay vào đó chúng ta cần sử dụng findlệnh có thể phân tách tên tệp bằng ký tự null ( -print0). Chúng ta cũng cần yêu cầu grep sử dụng các ký tự null để phân tách đầu vào ( -z) và đầu ra ( -Z). Cuối cùng, chúng tôi nói với xargs cũng sử dụng các ký tự null ( -0)

find . -type f -print0 | egrep '. ' -z -Z | xargs -0 rm



-1

Để làm theo cách đó, bạn sẽ cần -Ztùy chọn grep và -0tùy chọn xargs. Nhưng tôi sẽ không làm theo cách đó ( lskhông phải là công cụ phù hợp cho công việc, có nhiều vấn đề trong việc khiến máy tính đọc đầu ra của nó).

Xem câu trả lời khác cho một cách tốt hơn.


Cũng thế

ls | …tương đương với ls -d *echo * | …

Tất cả đều có vấn đề. Do đó, đừng sử dụng lsnhư thế này, hãy sử dụng giải pháp từ câu trả lời khác.


Ngoài ra ls *khi các đường ống xuất ra các tên tệp được phân cách dòng mới. echo(ít nhất là một số echotriển khai) mở rộng các chuỗi dấu gạch chéo ngược. grep -Zlà để viết tên tệp được phân định bằng NUL khi sử dụng -l, nó sẽ không giúp ích ở đây. Nếu bạn muốn nói -z, điều đó sẽ không giúp ích gì vì hầu hết các lstriển khai đều thiếu tùy chọn để xuất tên tệp NUL được phân tách. Người ta có thể làm một cái gì đó như printf '%s\0' * | grep -z ' ' | xargs -r0 rm -fmặc dù.
Stéphane Chazelas

1
@Kusalananda Tôi nghĩ rằng tôi đã sửa nó.
ctrl-alt-delor
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.