Câu trả lời:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdf
tệp kết thúc bằng tên tệpVí dụ: nếu có một thư mục được gọi temp
trong thư mục nhà của bạn:
cd ~/temp
sau đó xóa các tập tin:
find . -type f ! -iname "*.pdf" -delete
Điều này sẽ xóa tất cả các tập tin ngoại trừ xyz.pdf
.
Bạn có thể kết hợp hai lệnh này để:
find ~/temp -type f ! -iname "*.pdf" -delete
.
là thư mục hiện tại. !
có nghĩa là lấy tất cả các tập tin ngoại trừ những tập tin có .pdf
ở cuối. -type f
chỉ chọn các tập tin, không phải thư mục. -delete
có nghĩa là xóa nó
!
phải đến trước -name
. đơn giản -name
sẽ chỉ bao gồm .pdf
, trong khi -iname
sẽ bao gồm cả hai .pdf
và.PDF
Để chỉ xóa trong thư mục hiện tại và không trong thư mục con thêm -maxdepth 1
:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.
có nghĩa là thư mục hiện tại. !
có nghĩa là lấy tất cả các tệp ngoại trừ tệp có .pdf
ở cuối. -delete
có nghĩa là xóa nó tôi đã rõ chưa
-maxdepth 1
tham số để bắt đầu. Sau đó đề nghị xóa tham số trong trường hợp người ta muốn xóa đệ quy.
Với tính bash
năng mở rộng shell shell, bạn có thể xóa bất kỳ tệp nào có tiện ích mở rộng ngoài .pdf
việc sử dụng
rm -- *.!(pdf)
Theo ghi nhận của @pts, các --
ký tự chỉ ra sự kết thúc của bất kỳ tùy chọn lệnh nào, làm cho lệnh an toàn trong trường hợp hiếm hoi của các tệp có tên bắt đầu bằng một -
ký tự.
Nếu bạn muốn xóa các tệp mà không có bất kỳ tiện ích mở rộng nào cũng như các tiện ích mở rộng khác .pdf
, thì như @DennisWilliamson chỉ ra, bạn có thể sử dụng
rm -- !(*.pdf)
Mở rộng toàn cầu nên được bật theo mặc định, nhưng nếu không, bạn có thể làm như vậy bằng cách sử dụng
shopt -s extglob
Đặc biệt nếu bạn có ý định sử dụng tập lệnh này trong tập lệnh, điều quan trọng cần lưu ý là nếu biểu thức không khớp với bất cứ thứ gì (nghĩa là nếu không có tệp không phải pdf trong thư mục), thì theo mặc định, toàn cầu sẽ được chuyển sang chưa được mở rộng cho rm
lệnh, dẫn đến một lỗi như
rm: cannot remove `*.!(pdf)': No such file or directory
Bạn có thể sửa đổi hành vi mặc định này bằng nullglob
tùy chọn shell, tuy nhiên điều đó có vấn đề riêng. Để thảo luận kỹ hơn, xem NullGlob - Greg's Wiki
rm *~*.pdf
!(*.py)
. Ngoài ra, có lẽ, nếu OP chỉ muốn các tệp ".pdf" còn lại, thì các tệp không có phần mở rộng cũng sẽ bị xóa và không được bỏ qua.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Hoặc thông qua mv
lệnh (nhưng theo cách này, bạn không thể khôi phục nó từ Thùng rác vì nó không ghi thông tin .trashinfo, vì vậy điều này có nghĩa là bạn đã di chuyển các tệp của mình đến đích như sau).
mv !(*.pdf) ~/.local/share/Trash/files
rm
.
Cách tiếp cận đơn giản nhất: Tạo một thư mục khác ở đâu đó (nếu bạn chỉ xóa trong một thư mục, không đệ quy, nó thậm chí có thể là thư mục con); di chuyển tất cả .pdf ở đó; xóa mọi thứ khác; di chuyển trở lại của pdf; xóa thư mục trung gian.
Nhanh chóng, dễ dàng, bạn có thể thấy chính xác những gì bạn đang làm. Chỉ cần đảm bảo thư mục trung gian nằm trên cùng thiết bị với thư mục bạn đang dọn dẹp để di chuyển được đổi tên, không phải bản sao!
Sử dụng GLOBIGNORE của bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Từ trang người đàn ông của bash:
TOÀN CẦU: Một danh sách các mẫu được phân tách bằng dấu hai chấm xác định tập hợp tên tệp bị bỏ qua bởi mở rộng tên đường dẫn.
Một bài kiểm tra nhanh:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Đầu ra:
y.zip z.mp3
Đây là một cách tiếp cận tôi thích, vì nó cho phép tôi rất cẩn thận: soạn một cách để chỉ hiển thị các tệp tôi muốn xóa, sau đó gửi chúng cho rm
sử dụng xargs
. Ví dụ:
ls
cho tôi xem tất cảls | grep pdf
cho tôi xem các tập tin tôi muốn giữ Hừm.ls | grep -v pdf
cho thấy điều ngược lại: tất cả ngoại trừ những gì tôi muốn giữ. Nói cách khác, nó hiển thị danh sách những thứ tôi muốn xóa. Tôi có thể xác nhận điều này trước khi làm bất cứ điều gì nguy hiểm.ls | grep -v pdf | xargs rm
gửi chính xác danh sách đó để rm
xóaNhư tôi đã nói, tôi chủ yếu thích điều này vì sự an toàn mà nó mang lại: không có sự tình cờ rm *
đối với tôi. Hai lợi thế khác:
ls
hoặc find
để có được danh sách ban đầu, tùy thích. Bạn có thể sử dụng bất cứ thứ gì bạn thích trong quá trình thu hẹp danh sách đó - một cái khác grep
, một số awk
hoặc bất cứ thứ gì. Nếu bạn chỉ cần xóa các tệp có tên chứa màu, bạn có thể tạo nó theo cách tương tự.find
để tìm và rm
loại bỏ, trái ngược với việc phải nhớ rằng find
chấp nhận một -delete
lá cờ. Và nếu bạn làm điều này, một lần nữa, bạn có thể soạn các giải pháp thay thế; có thể thay vì rm
, bạn có thể tạo một trash
lệnh di chuyển tệp vào thùng rác (cho phép "hủy xóa") và chuyển sang đó thay vì rm
. Bạn không cần phải có find
hỗ trợ tùy chọn đó, bạn chỉ cần chuyển sang tùy chọn đó.Xem bình luận của @pabouk để biết cách sửa đổi điều này để xử lý một số trường hợp cạnh, chẳng hạn như ngắt dòng trong tên tệp, tên tệp như my_pdfs.zip
, v.v.
pdf
nào có chứa bất cứ nơi nào trong tên của nó. --- b) Nó sẽ xóa các tệp PDF nếu bất kỳ chữ cái nào trong hậu tố là chữ hoa. --- c) Không nên sử dụng đầu ra của ls
. Nó sẽ không hoạt động với tên tập tin có chứa dòng mới. Một số triển khai ls
thay thế các ký tự đặc biệt, ví dụ: tab bằng ?
. --- Tốt hơn là sử dụng : find -maxdepth 1 -print0
. (không quá ngắn như ls
:) ----- Để giải quyết a) và b) sử dụng grep -vi '\.pdf$'
giải pháp --- hoàn thành (nhưng chỉ GNU):find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20
ít nhất bạn có thể xem liệu nó có trông gần đúng không, trong khi nếu bạn chỉ rm my_pattern
, bạn không có cơ hội phát hiện ra một sai lầm lớn.
find . -type f ! -name "*.pdf"
để in ra bàn điều khiển, hoặc dẫn đến ít hoặc một tập tin. [và sau đó chuyển sang xargs thành rm nếu muốn như nhận xét của pabouk (với -print0 | ... -0 cho tên tệp lạ)]
Tôi thường giải quyết các vấn đề như vậy từ trình thông dịch Python tương tác:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Nó có thể dài hơn một lớp lót với find
hoặc xargs
, nhưng nó cực kỳ đàn hồi và tôi biết chính xác nó làm gì mà không cần phải nghiên cứu trước.
for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
câu trả lời tốt hơn (so với câu trả lời trước của tôi) cho câu hỏi này sẽ bằng cách sử dụng file
lệnh mạnh mẽ .
$ file -i abc.pdf
abc: application/pdf; charset=binary
bây giờ vấn đề của bạn:
cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done
công việc của for
lệnh là đưa ra các tệp trong thư mục hiện tại dưới dạng biến $var
. if-then
lệnh xuất ra tên của các tệp pdf bằng cách lấy trạng thái thoát 0
khỏi file -i "$var" | grep -q 'application/pdf\;'
lệnh, nó sẽ chỉ đưa ra trạng thái thoát 0
nếu tìm thấy tệp pdf.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Cảnh báo! Tốt nhất hãy thử trước
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-i
với grep
cho phù hợp với case-insensitive.
rm -i -- !(*@(a|x).pdf)
Đọc dưới dạng, xóa tất cả các tệp không a.pdf
hoặc x.pdf
.
Điều này hoạt động bằng cách sử dụng 2 khối lượng mở rộng, bên ngoài !()
để phủ định quả cầu chứa trong đó đòi hỏi quả cầu phải khớp với một hoặc nhiều a
hoặc x
các mẫu trước .pdf
hậu tố. Xem toàn cầu # extglob .
$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3
$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3
$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3
$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3
$ echo -- !(@(a|x).pdf) # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3
$ echo -- !(*@(a|x).pdf) # but this doesn't
-- y.zip z.mp3
$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3
$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'
Khá nhiều POSIX và tương thích với bất kỳ shell Bourne-style ( ksh
, bash
, dash
). Rất phù hợp cho các tập lệnh di động và khi bạn không thể sử dụng toàn bash
cầu shell mở rộng.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Hoặc sạch hơn một chút:
$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'
python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'
Hãy cẩn thận với những gì bạn đang xóa!
Một cách an toàn để kiểm tra nó trước khi thử xóa là kiểm tra trước ls
, vì một số hành vi chưa được kiểm tra có thể xóa các tệp không mong muốn. Và bạn có thể làm điều đó trực tiếp bên ngoài thư mục. ls
tương tự như rm
vậy, vì vậy:
ls sub/path/to/files/!(*.pdf)
Điều này sẽ liệt kê
y.zip
z.mp3
Và bây giờ bạn có thể thấy những gì bạn đang xóa và có thể xóa chúng một cách an toàn:
rm sub/path/to/files/!(*.pdf)
Và đó là nó. Bạn có thể sử dụng ký tự đại diện *
để chọn lọc hơn như chỉ giữ các tài liệu khóa học lập trình:
rm sub/path/to/files/!(*programming*)
.
có nghĩa là "và"?!
có nghĩa là "ngoại trừ"-name
biểu thị rằng bạn muốn loại trừ bởi một tham số tên và sau đó-delete
là hành động để thực hiện khi tìm kiếm? Vì vậy, nó tìm kiếm mọi thứ trừ "* .pdf" và xóa chúng? Hay tôi đã hiểu lầm?