Я столкнулся с проблемой кодирования при копировании большого количества файлов и папок из системы Windows в систему Linux, и теперь я вижу множество файлов с вопросительным знаком в названии.

Я хотел бы знать, сколько файлов / папок затронуто, и поэтому я попытался

find . -type d -o -type f -name '*\?*'

а также

find . -type d -o -type f -name '*?*'

без удачи

В нем перечислено много файлов / папок, в имени которых нет знака вопроса ... (обратите внимание, что поиск должен быть рекурсивным)

У тебя есть решение ?

(Кроме того, если у вас есть вторая команда для подсчета количества файлов, на которые я воздействую, я был бы счастлив :))

[edit] Спасибо за ваши ответы, но проблема в том, что эти файлы и папки исключены из команды find из-за проблемы с кодировкой. Во-первых, кажется, что это не так? характер, но больше что-то вроде �. И я пытаюсь выполнить поиск по какой-то другой части их имени, и они все еще не появляются (если я переименую их, я избавлюсь от проблемы с кодировкой, и они снова станут видимыми, чтобы find).
Это помогло мне перечислить и посчитать их.

Спасибо

3 ответа3

1

У вас есть проблема с кодировкой, которая должна быть решена.

? отображается ls является заполнителем и не означает, что файл назван ? ,

Вот как воспроизвести вашу проблему, используя iconv, в обычной системе Linux с настройкой utf8:

$ mkdir /tmp/test
$ cd /tmp/test
$ touch $(echo é | iconv -t windows-1252) # that's the eacute character
$ ls
?
$ ls|cat
�

Последняя строка просто означает "отображается неверная кодировка utf8" и, вероятно, не может быть правильно скопирована / вставлена без потери ее информации. windows-1252 является лишь примером. Это могло быть много других (например: iso-8859-1). Информация все еще там:

$ ls|iconv -f windows-1252
é

Поэтому, как только вы выясните, какая кодировка использовалась для записи этих файлов в Linux (попробуйте iconv -l|egrep -i 'win|iso-8859' для списка возможных кандидатов), вы можете попробовать переименовать пакет. Будьте осторожны, хотя пример может работать, он может не сработать для другого файла.

Пример переименования:

ENCODING="windows-1252" # once the right encoding was found
for file in *; do
    dest="$(printf '%s' "$file" | iconv -f "$ENCODING")"
    mv -i "$file" "$dest.new"
    mv -i "$dest.new" "$dest"
done
0

find 's -o означает " или ", так что у вас может быть проблема с прецедентами ...

Что вы имели в виду?

  • -type d или (-type f и -name '*\?*')
    • все каталоги
    • все файлы с ? во имя
  • (-type d или -type f) и -name '*\?*'
    • только каталоги и файлы с ? во имя

Вы можете использовать фигурные скобки с find , поэтому ваша команда становится:

find . \( -type d -o -type f \) -name '*\?*'

Пример:

$ touch 'aaa' 'a?a'
$ mkdir 'bbb' 'b?b'
$ touch 'bbb/ccc' 'bbb/c?c'
$ find . -type d -o -type f -name '*\?*'
.
./bbb
./bbb/c?c
./b?b
./a?a
$ find . \( -type d -o -type f \) -name '*\?*'
./bbb/c?c
./b?b
./a?a

Затем вы можете передать вывод в wc -l для подсчета количества строк:

$ find . \( -type d -o -type f \) -name '*\?*' | wc -l
3

Другие предлагают удалить -type d -o -type f . Это хороший вариант, если только вы не пытаетесь исключить другие типы (например: блочное устройство / символьное устройство / символические ссылки / каналы / сокеты)

0

Ваша первая команда может быть изменена следующим образом:

find . -type d  -name '*\?*' -o -type f -name '*\?*'

Таким образом, фильтр применяется как к файлам, так и к каталогам (в противном случае вы бы перечислили все каталоги и только файлы фильтров).


Гораздо проще, как предложено Jimmy_A в комментариях, было бы:

find . -name '*\?*'

Обратите внимание, что find выполняется по умолчанию в текущем каталоге, поэтому . также может быть опущено:

find -name '*\?*'

В качестве альтернативы вы можете получить результаты:

find | grep ?

Для подсчета соответствующих объектов (решение, предложенное Jimmy_A):

find | grep ? | wc -l

команда для подсчета количества файлов

Чтобы считать только файлы, как вы, кажется, просите:

find -type f | grep ? | wc -l

Тестовый забег:

?aa
a?a
aa?
aaa
$ find | grep ?
./a?a
./?aa
./aa?

Комментарий:

Я думал, что grep понадобится опция -F для лечения ? в буквальном смысле, но, похоже, в любом случае это не считается специальным символом, если только не используется ключ -E .

   -F, --fixed-strings
          Interpret PATTERN as a list of fixed strings (instead of regular expressions), separated by newlines, any of which is to be matched.

   -E, --extended-regexp
          Interpret PATTERN as an extended regular expression (ERE, see below).

Вопрос был обновлен:

Перечислите все файлы и папки, в имени которых есть знак вопроса (�)

Не так много изменений: либо find -name '*�*' либо find | grep �

Тестовый забег:

�aa
a�a
aa�
aaa
$ find -name '*�*'
./a�a
./�aa
./aa�

Еще одна проблема:

Если вы хотите найти файлы или каталоги, содержащие экзотические символы, вы можете отфильтровать результаты, указав, какие символы вы ожидаете. Просто добавьте в список любой символ, который вы не хотите выделять:

find | grep -P '[^\w./-_*]'

Это особенно полезно, когда вы не знаете, какой из проблемных персонажей. Пожалуйста, обратите внимание, что это вопрос, на который уже несколько раз задавались вопросы и ответы на Stackexchange.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .