Неможливо видалити / перемістити файли зі спеціальними символами у назві файлу


17

Як видно нижче, файли мають незвичайні символи.

скріншот файлового менеджера

Видалення їх або в терміналі, або в Dolphin повертає помилку:

Немає такого файлу чи каталогу

Запуск ls -laу каталозі дав мені такий вихід:

-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ?2?.???љ?!?Gb??σ?[?F?
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 3l??#g?w????O?JKB7?co??քH??bT?NA???S???X?I?A?qC??M?I???
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??8??-?@,?Zp?[?bI????7^?ñ[?ڏ??z?O???ч??eEȰ?+??,OF??h

Я запустив fsckкоманду на розділі з іншої ОС, але це нічого не змінило.

Як видалити ці файли?


1
Ви налаштували свою систему на зашифрований домашній каталог?
добі

@dobey я цього не зробив.
karjedavpalaa

5
@Panther Ви помиляєтесь. Це НЕ сам по собі, свідчить про корумповану файлової системи, і навіть якщо вона була викликана пошкодженням даних деякого виду, Fsck не зробити нічого про нього.
zwol


1
У мене були файли з невпізнаними символами в імені. Перейменування працюючих файлів. тоді їх можна буде видалити.
ravery

Відповіді:


35

Найпростішим способом було б видалення цих файлів за їх inode. :)

Використовуйте ls -liв каталозі нечасті символи, щоб показати номер inode кожного файлу, наприклад,

$ ls -li
total 0
133370 -rw-r--r-- 1 malte malte 0 Dec 30 19:00 ?2?.???љ?!?Gb??σ?[?F?
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

Далі за допомогою findутиліти видаліть відповідний файл за його іменем, використовуючи синтаксис find <somepath> -inum <inode_number> -exec rm -i {} \;, як у наступному прикладі:

$ find . -inum 133370 -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
$ ls -li
total 0
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

Цей -iпараметр rmнасправді не потрібен, я просто додав його, щоб запобігти випадковому видаленню файлів, які ви не хотіли видаляти. :) Це викликає rmзапит підтвердження кожного файлу, який ви хочете видалити.

Якщо ви хочете видалити кілька файлів за їхніми індексами, ви можете використовувати синтаксис -o(що означає або ) для find:

$ find .  \( -inum 133370 -o -inum 132584 \) -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
rm: remove regular empty file ‘./??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??’? y

Ви можете додати більше чисел inode, розширивши вираз у дужках із більшою кількістю -o -inum <inode_number>виразів.


4
Як щодо rm -ri .?
Brent Baccala

Це спрацювало: знайдіть <somepath> -inum <inode_number> -exec rm -i {} \; Що в команді роблять '-inum', '{}' та '\'?
karjedavpalaa

Як видалити кілька файлів за один раз? Також, дякую, ти зробив мій день!
karjedavpalaa

2
@BrentBaccala rm -ri .не видаляє файли за допомогою inode. Він просто повториться через весь робочий каталог і запитає кожен файл, якщо ви хочете його видалити - і ви повинні бути дуже уважними, які файли він просить, щоб випадково не видалити непотрібні. Я, звичайно, не хотів би використовувати цю команду для мого домашнього каталогу - вона містить багато файлів. ;)
Malte Skoruppa

3
@karjedavpalaa (1) -inumповідомляє findшукати файли за їх номером inode. (2) {}відповідає файлу, знайденому користувачем grep. (3) \ ухиляється від ;символу, який припиняє команду, передану -execопції find. (4) Я відредагував свою відповідь, щоб пояснити, як видалити кілька файлів за один раз.
Malte Skoruppa

13

Важливо розуміти, що це не такий тип «пошкодження файлової системи», який fsckдопоможе. Що стосується файлової системи, то назви файлів можуть бути будь-якою послідовністю байтів , якщо жоден байт не має значення 0x00 (ASCII NUL, маркер кінця рядка) або 0x2F ( /роздільник каталогів). (Якщо ім'я файлу якось вбудовано в нього байт 00 або 2F, fsckслід це виправити.)

Вірніше, що у вас є назви файлів, які, на думку прикладного програмного забезпечення (Dolphin, ls), містять символи, які неможливо відобразити у вашому "локалі", тому це замінює їх символами-заповнювачами. Ви також не можете вводити ці символи, тому маніпулювати файлами складніше, але ви можете робити це до тих пір, як це зробите, не вводячи і копіюючи і не вставляючи ім'я. Наприклад, якщо ви видалите або перейменуєте проблемні файли безпосередньо з Dolphin, це повинно просто працювати (я б пішов так далеко, щоб сказати, що якщо він не працює, це помилка в Dolphin).

Якщо вам потрібно зробити щось із них із оболонки (наприклад, якщо вони належать rootі тому не можуть бути змінені програмою GUI), ви можете назвати їх побічно, використовуючи шаблони "glob", які будуть розширені до правильної послідовності (и) байтів і передано разом.

Тепер, звичайно, ви не хочете видаляти речі випадково, оскільки ваш глобальний зразок збігається занадто багато, тому моя рекомендація буде використовувати renameутиліту Perl для перетворення кожного імені файлу в його шістнадцяткове кодування:

$ rename '$_ = unpack("H*", $_)' *

Це не знищує жодної інформації - ні сам файл, ні будь-яке значення, можливо, спочатку не було закодовано в ім'я файлу до того, як воно було заблукало. Її можна скасувати для конкретних файлів, наприклад,

$ rename '$_ = pack("H*", $_)' 696d706f7274616e742e646f63

Обережно: є дві програми, названі renameрізного походження; вищезазначені команди працюватимуть лише з тим, що походить з Perl. В Ubuntu потрібний той, який ви хочете отримати з пакету "перейменувати", а не пакет "util-linux". rename -hрозрізнимо: це те, що ти хочеш ...

$ rename -h
Usage:
    rename [ -h|-m|-V ] [ -v ] [ -n ] [ -f ] [ -e|-E perlexpr]*|perlexpr
    [ files ]
# ...

... це не те, що ти хочеш ...

$ rename -h

Usage:
 rename [options] <expression> <replacement> <file>...
# ...

Ключове, на що слід звернути увагу, - «perlexpr». Можливо, у вас є старіша версія перейменування Perl, яка не розуміє всіх наведених вище варіантів, але команда, яку я показав, все одно повинна працювати.

Редагувати: Під 14.04 .5 сценарій perl, який включений rename, не підтримує перемикач -h. Ви можете підтвердити, що у вас є правильний, перевіривши його чоловічу сторінку, і man renameв цьому випадку верхній рядок буде містити:

RENAME (1) Посібник для програмістів Perl RENAME (1)


перейменувати - перехід Невідомий варіант: версія
Старійшина Гік

@ElderGeek Що file $(which rename)друкує? (Переконайтесь, що у вас встановлений fileпакет.)
zwol

/usr/bin/rename: symbolic link to /etc/alternatives/rename( fileвстановлено за замовчуванням) Насправді вам потрібно переслідувати символічні посилання, щоб отримати, /usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable але man renameце швидше вказівка ​​...
Старійшина Geek

@ElderGeek Якщо це сценарій perl, то, ймовірно, це старіша версія "тієї, що походить з Perl", яка не підтримує --version; команда, яку я запропонував, все одно повинна працювати. (/usr/share/doc/rename/changelog.gz на моєму комп’ютері, на якому працює Debian нестабільно, вказує, що --versionдодано у версії 0.10 перейменування Perl, у 2013 році. Я здивований, що Ubuntu все ще доставляє щось старіше за це, але ця програма фактично не змінила свою функціональність з 2007 року (!), тому це добре.)
zwol

Ах! Це пояснює плутанину. Незважаючи на багато претензій на протилежне, Debian не є Ubuntu. Я не можу говорити про кожен реліз, але деякі підтримувані в даний час версії Ubuntu LTS (14.04) все ще не мають цього. (Хоча 16.04 так)
Старійшина Гік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.