Предположение, которое "внешний" означает "не символ ASCII", затем можно использовать find
с шаблоном для нахождения всех файлов, не имеющих печатаемые символы ASCII на их имена:
LC_ALL=C find . -name '*[! -~]*'
(Пространство является первым печатаемым символом, перечисленным на http://www.asciitable.com/, ~
является последним.)
Подсказка для LC_ALL=C
требуется (на самом деле, LC_CTYPE=C
и LC_COLLATE=C
), иначе диапазон символов интерпретируется неправильно. См. также страницу руководства glob(7)
. С тех пор LC_ALL=C
причины find
для интерпретации строк как ASCII это распечатает многобайтовые символы (такой как π
) как вопросительные знаки. Для фиксации этого передайте по каналу к некоторой программе (например. cat
) или перенаправление в файл.
Вместо того, чтобы указать диапазоны символов, [:print:]
может также использоваться для выбора "печатаемых символов". Обязательно установите локаль C, или Вы получаете вполне (на вид) произвольное поведение.
Пример:
$ touch $(printf '\u03c0') "$(printf 'x\ty')"
$ ls -F
dir/ foo foo.c xrestop-0.4/ xrestop-0.4.tar.gz π
$ find -name '*[! -~]*' # this is broken (LC_COLLATE=en_US.UTF-8)
./x?y
./dir
./π
... (a lot more)
./foo.c
$ LC_ALL=C find . -name '*[! -~]*'
./x?y
./??
$ LC_ALL=C find . -name '*[! -~]*' | cat
./x y
./π
$ LC_ALL=C find . -name '*[![:print:]]*' | cat
./x y
./π
Если Вы переводите каждое использование имени файла tr -d '[\200-\377]'
и сравните его с настоящим именем, затем любые имена файлов, которые имеют специальные символы, не будут тем же.
(Вышеупомянутое предположение, что Вы имеете в виду неASCII с внешним),
[
и ]
s).спасибо.
– suspectus
17.01.2014, 14:26
Можно использовать tr
удалить любой внешний символ из имени файла и сравнить результат с исходным именем файла, чтобы видеть, содержало ли это внешние символы.
find . -type f > filenames
while read filename; do
stripped="$(printf '%s\n' "$filename" | tr -d -C '[[:alnum:]][[:space:]][[:punct:]]')"
test "$filename" = "$stripped" || printf '%s\n' "$filename";
done < filenames
find
вывод, используйте NUL-завершенный вывод/вход как показано в этом ответе.
– Lekensteyn
17.01.2014, 13:20
Принятый ответ полезен, но если ваши имена файлов уже находятся в кодировке, указанной в LANG
/LC_CTYPE
, лучше просто сделать:
LC_COLLATE=C find. -name '*[! -~]*'
На классы символов влияет LC_CTYPE
, но приведенная выше команда не использует классы символов, а использует только диапазоны, поэтому LC_CTYPE
просто предотвращает замену необычных символов вопросительными знаками.
LC_ALL=C
вместоLC_COLLATE=C
поскольку это, не имеет большого смысла устанавливать LC_COLLATE на C без установкиLC_CTYPE
и удостоверяться это все еще работает, даже когда переменная LC_ALL находится в среде. – Stéphane Chazelas 17.01.2014, 13:47SPC
является печатаемым, затем что относительноTAB
иLF
которые также обычно находятся в текстовых файлах? – Stéphane Chazelas 17.01.2014, 13:56LC_COLLATE
иLC_CTYPE
, см. такжеfind(1)
страница справочника. – Lekensteyn 17.01.2014, 14:44