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

Как вы можете видеть ниже, файлы имеют необычные символы.

file manager screenshot

Удаление их либо в терминале, либо в 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 на разделе из другой ОС, но это ничего не изменило.

Как мне удалить эти файлы?

17
задан 2 January 2018 в 12:53

3 ответа

Простым способом было бы удалить эти файлы по их иноду. :)

Используйте ls -li в каталоге с необычными символами, чтобы показать номер инода каждого файла, например,

$ 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 запрашивать подтверждение для каждого файла, который вы хотите удалить.

Если вы хотите удалить несколько файлов по их inode, вы можете использовать синтаксис -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

Вы можете добавить еще номера индексов, расширяя выражение в скобках с помощью более -o -inum <inode_number> выражений.

34
ответ дан 2 January 2018 в 12:53

Важно понять, что это не вид "повреждения файловой системы" это fsck поможет с. Что касается файловой системы, имена файлов могут быть любой последовательностью байтов, пока никакой единственный байт не имеет значение 0x00 (ASCII NUL, C маркер конца строки) или 0x2F (/, разделитель каталога). (Если имя файла действительно так или иначе получает 00 или 2F байт, встроенный в нем, fsck должен зафиксировать это.)

Скорее что Вы имеете, имена файлов что прикладное программное обеспечение (дельфин, ls) думайте содержат символы, которые являются невизуализуемыми в Вашей "локали", таким образом, она заменяет их символами заполнителя. Вы не можете ввести те символы или, так управление файлами более трудно, но можно сделать это, пока Вы делаете это, никогда не вводя или копируя и вставляя имя. Например, если Вы удаляете или переименовываете проблемные файлы непосредственно из дельфина, который должен Просто Работать (я сказал бы даже, что, если он не работает, это - ошибка у дельфина).

Если необходимо сделать что-то о них от оболочки (например, если они принадлежат root и поэтому не может быть изменен программой GUI), можно назвать их косвенно использованием шаблонов "шарика", которые будут расширены до корректной последовательности (последовательностей) байтов и проведены.

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

$ 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 сценарий жемчуга это включено для rename не поддерживает переключатель-h. Можно подтвердить, что у Вас есть корректный путем проверки, что это - страница справочника с man rename в этом случае верхняя строка будет содержать:

ПЕРЕИМЕНУЙТЕ (1), справочник программистов Perl ПЕРЕИМЕНОВЫВАЕТ (1)

13
ответ дан 2 January 2018 в 12:53

Я бы порекомендовал Midnight Commander - файловый менеджер на базе терминала. Это первый и, вероятно, самый полезный программный инструмент, который я устанавливаю в любой системе.

Это позволит вам выбирать файлы с помощью указателя и щелчка (если у вас включена консольная мышь через gpm) или с помощью курсора и клавиш Ins.

Выбрав файлы, нажмите F8, чтобы удалить их.

Нет необходимости вводить имена файлов или переименовывать файлы, но вам может понадобиться запустить Midnight Commander от имени sudo.

0
ответ дан 8 October 2020 в 21:30

Другие вопросы по тегам:

Похожие вопросы: