Відповіді:
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" та видаляє їх? Або я неправильно зрозумів?