Câu trả lời:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdftệp kết thúc bằng tên tệpVí dụ: nếu có một thư mục được gọi temptrong 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 fchỉ chọn các tập tin, không phải thư mục. -deletecó nghĩa là xóa nó
!phải đến trước -name. đơn giản -namesẽ chỉ bao gồm .pdf, trong khi -inamesẽ bao gồm cả hai .pdfvà.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. -deletecó nghĩa là xóa nó tôi đã rõ chưa
-maxdepth 1tham 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 bashnă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 .pdfviệ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 rmlệ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 nullglobtù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 mvlệ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 rmsử dụng xargs. Ví dụ:
ls cho tôi xem tất cảls | grep pdfcho tôi xem các tập tin tôi muốn giữ Hừm.ls | grep -v pdfcho 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 rmgửi chính xác danh sách đó để rmxó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:
lshoặ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ố awkhoặ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à rmloại bỏ, trái ngược với việc phải nhớ rằng findchấp nhận một -deletelá 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 trashlệ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ó findhỗ 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.
pdfnà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 lsthay 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 findhoặ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 filelệ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 forlệnh là đưa ra các tệp trong thư mục hiện tại dưới dạng biến $var. if-thenlệ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 0khỏi file -i "$var" | grep -q 'application/pdf\;'lệnh, nó sẽ chỉ đưa ra trạng thái thoát 0nế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}')
-ivới grepcho 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.pdfhoặ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 ahoặc xcác mẫu trước .pdfhậ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 bashcầ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. lstương tự như rmvậ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ừ"-namebiểu thị rằng bạn muốn loại trừ bởi một tham số tên và sau đó-deletelà 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?