Відповіді:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdfна ім'я файлуНаприклад, якщо tempу вашій домашній папці є каталог:
cd ~/temp
потім видаліть файли:
find . -type f ! -iname "*.pdf" -delete
Це видалить усі файли, крім xyz.pdf.
Ви можете об'єднати ці дві команди для:
find ~/temp -type f ! -iname "*.pdf" -delete
.- поточний каталог. !означає взяти всі файли, окрім файлів, що мають .pdfкінець. -type fвибирає лише файли, а не каталоги. -deleteозначає видалити його.
!повинні прийти раніше -name. просто -nameбуде включати тільки .pdf, в той час як -inameбуде включати в себе і те, .pdfі.PDFЩоб видалити тільки в поточному каталозі, а не в підкаталогах, додайте -maxdepth 1:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.означає поточний каталог. !означає взяти всі файли, окрім файлів, що мають .pdfкінець. -deleteозначає видалити його. я зрозумів зараз?
-maxdepth 1параметр для початку. Потім запропонуйте видалити параметр у випадку, якщо потрібно видалити рекурсивно.
Завдяки bashрозширенню глобальної оболонки ви можете видалити будь-які файли з розширеннями, крім .pdfвикористання
rm -- *.!(pdf)
Як зазначає @pts, --символи вказують на завершення будь-яких параметрів команди, роблять команду безпечною у рідкісних випадках файлів, імена яких починаються з -символу.
Якщо ви хочете видалити файли без будь-якого розширення, а також ті, що мають не інші розширення .pdf, то, як вказував @DennisWilliamson, ви можете використовувати
rm -- !(*.pdf)
Розширений глобул повинен бути включений за замовчуванням, але якщо ні, то ви можете зробити це за допомогою
shopt -s extglob
Особливо, якщо ви маєте намір використовувати це всередині сценарію, важливо зауважити, що якщо вираз нічого не відповідає (тобто, якщо в каталозі немає файлів, що не належать до формату pdf), то за замовчуванням глобус буде передано нерозгорнуто до rmкоманда, в результаті чого виникає помилка
rm: cannot remove `*.!(pdf)': No such file or directory
Ви можете змінити цю поведінку за замовчуванням за допомогою параметра nullglobоболонки, однак у неї є своя проблема. Для більш ретельного обговорення див. NullGlob - Вікі Грега
rm *~*.pdf
!(*.py). Також, імовірно, якщо ОП хоче лише залишитися лише файлами ".pdf", то файли без розширень також слід видалити і не ігнорувати.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Або за допомогою mvкоманди (але таким чином ви не можете відновити його з кошика, оскільки він не записує .trashinfo інформацію, тож це означає, що ви перемістили файли до місця призначення, де воно є наступним).
mv !(*.pdf) ~/.local/share/Trash/files
rm.
Найпростіший підхід: створити інший каталог десь (якщо ви видаляєте лише в одному каталозі, а не рекурсивно, це навіть може бути підкаталог); перемістити всі файли .pdf туди; видалити все інше; перемістити назад PDF-файл; видалити проміжний каталог.
Швидко, просто, ви можете точно бачити, що ви робите. Просто переконайтеся, що проміжний каталог знаходиться на тому ж пристрої, що і каталог, який ви очищаєте, щоб переміщення були перейменованими, а не копіями!
Використовуйте GLOBIGNORE bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
З сторінки чоловіка bash:
GLOBIGNORE:
Список візерунків, розділених двокрапкою, визначає набір
імен файлів, які слід ігнорувати шляхом розширення імені шляху.
Швидкий тест:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Вихід:
y.zip z.mp3
Ось такий підхід мені подобається, тому що він дозволяє мені бути дуже обережним: складіть спосіб показати лише ті файли, які я хочу видалити, а потім надішліть їх до rmвикористання xargs. Наприклад:
ls показує мені всеls | grep pdfпоказує мені файли, які я хочу зберегти. Хм.ls | grep -v pdfпоказує протилежне: все, крім того, що я хочу зберегти. Іншими словами, він показує список речей, які я хочу видалити. Я можу це підтвердити, перш ніж робити щось небезпечне.ls | grep -v pdf | xargs rmнадсилає саме цей список rmдля видаленняЯк я вже сказав, мені це в основному подобається за безпеку, яку він забезпечує: rm *для мене немає випадкових випадків . Ще дві переваги:
lsабо findотримати початковий список, як вам зручніше. Ви можете використовувати все, що завгодно, у процесі звуження цього списку - іншого grep, деяких awkчи будь-чого іншого. Якщо вам потрібно було видалити лише файли, імена яких містять колір, ви можете створити його таким же чином.findдля пошуку та rmвидалення, на відміну від того, щоб пам’ятати, що findприймає -deleteпрапор. І якщо ви це зробите, знову ж таки, ви можете скласти альтернативні рішення; можливо, замість цього rm, ви можете створити trashкоманду, яка переміщує файл у кошик (що дозволяє "вимкнути") і передавати на нього замість rm. Вам не потрібно мати findпідтримку цієї опції, ви просто пропонуєте її.Перегляньте коментарі @pabouk про те, як змінити це для оброблення деяких кращих випадків, таких як розриви рядків у назвах файлів, назви імен файлів my_pdfs.zipтощо.
pdfдесь його ім’я. --- б) Він видалить файли PDF, якщо будь-який лист у суфіксі є великим регістром. --- в) Недоцільно використовувати вихід ls. Він не працюватиме з іменами файлів, що містять нові рядки. Деякі реалізації lsзамінюють спеціальні символи, наприклад, вкладку ?. --- Краще використовувати: find -maxdepth 1 -print0. (не настільки короткий, як ls:) ----- Для вирішення а) та б) використовуйте grep -vi '\.pdf$'--- повне (але тільки GNU) рішення:find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20принаймні побачити, чи це виглядає приблизно правильно, тоді як, якщо ви просто rm my_pattern, у вас немає шансів помітити велику помилку.
find . -type f ! -name "*.pdf"для друку на консоль, або передайте менше або файл. [а потім перейдіть до xargs до rm за бажанням, як коментарі pabouk (з -print0 | ... -0 для дивних файлів)]
Зазвичай я вирішую такі проблеми від інтерактивного інтерпретатора Python:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Це може бути довше, ніж однолінійний з, findабо xargs, але він надзвичайно стійкий, і я точно знаю, що це робить, не потребуючи попереднього дослідження.
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')]
краща відповідь (порівняно з моєю попередньою відповіддю) на це запитання буде за допомогою потужної fileкоманди.
$ file -i abc.pdf
abc: application/pdf; charset=binary
тепер ваша проблема:
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
завданням forкоманди є надання файлів у поточному каталозі у вигляді змінної $var. if-thenкоманда виводить імена файлів pdf, приймаючи статус виходу 0з file -i "$var" | grep -q 'application/pdf\;'команди, вона надасть статус виходу 0лише у тому випадку, якщо вона знайде файли pdf.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Увага! Краще спробуйте спочатку
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-iз grepдля обліку регістра відповідності.
rm -i -- !(*@(a|x).pdf)
Читати як, видалити всі файли, які не є a.pdfабо x.pdf.
Це працює, використовуючи 2 розширені глобуси, зовнішні !()для того, щоб заперечувати міститься глобус, який сам вимагає, щоб глобус повинен відповідати одному або більше aабо xшаблонам перед .pdfсуфіксом. Дивіться глобус # 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'
Досить багато POSIX і сумісний з будь-оболонкою Bourne стилю ( ksh, bash, dash). Добре підходить для портативних сценаріїв, і коли ви не можете використовувати bashрозширену глобальну оболонку.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Або трохи чистіше:
$ 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(".")))'
Будьте уважні до того, що ви видаляєте!
Безпечний спосіб перевірити його перед спробою видалити - це спробувати спочатку ls, оскільки деякі неприховані поведінки можуть видалити небажані файли. І це можна зробити безпосередньо за межами каталогу. lsподібний rm, так:
ls sub/path/to/files/!(*.pdf)
Це буде список
y.zip
z.mp3
Тепер ви можете побачити, що ви видаляєте, і можете їх безпечно видалити:
rm sub/path/to/files/!(*.pdf)
І це все. Йо може використовувати підстановку, *щоб бути більш вибірковою, як зберігання лише програмних документів курсу:
rm sub/path/to/files/!(*programming*)
.означає "і"?!означає "крім"-nameозначає, що ви хочете виключити параметр імені, а потім-deleteдія, яку слід вжити при пошуку? Отже, він шукає все, крім "* .pdf" та видаляє їх? Або я неправильно зрозумів?