В большом каталоге в моей системе Ubuntu (> 140 000 файлов и> 200 подкаталогов), я знаю, что где-нибудь существует два файла с именами слишком долго для копирования в папку Windows (NTFS). Я попробовал его и получил два сообщения об ошибках, но я не обращал внимание на то, в каких подпапках файлы были.
Как я могу найти эти два файла с самыми длинными именами?
Я предполагаю, что решением @steeldriver является лучший выбор однако, вот мое альтернативное решение, можно использовать комбинации команд для нахождения точно два (или больше) самые долгие имена файлов.
find . | awk 'function base(f){sub(".*/", "", f); return f;} \
{print length(base($0)), $0}'| sort -nr | head -2
вывод был бы похож:
length ./path/to/file
Здесь реальный пример:
42 ./path/to/this-file-got-42-character-right-here.txt
31 ./path/to/this-file-got-31-character.txt
find
дает нам список всех файлов в рамках того каталога как:
./path/to/this-file-got-31-character.txt
использование awk
мы добавляем длину файла для запуска каждой строки (это - точно длина файла не путь):
31 ./path/to/this-file-got-31-character.txt
наконец мы сортируем его на основе длины файла и получаем первые два использования строки head
.
На основе комментариев, в чем Вы действительно нуждаетесь в этом случае, список всех файлов, имена которых длиннее, чем некоторое максимальное количество символов - и к счастью это - относительно легкое использование a find
regex:
find $PWD -regextype posix-extended -regex '.*[^/]{255,}$'
Для такого большого количества файлов и каталогов, Вы, вероятно, не хотите сортировать - вместо этого, позвольте нам просто вести рабочий учет самых долгих и вторых по длине имен файлов и их полные пути:
find $PWD -printf '%p\0' | awk -v RS='\0' '
{
# get the length of the basename of the current filepath
n = split($0,a,"/");
currlen = length(a[n]);
if (currlen > l[1]) {
# bump the current longest to 2nd place
l[2] = l[1]; p[2] = p[1];
# store the new 1st place length and pathname
l[1] = currlen; p[1] = $0;
}
else if (currlen > l[2]) {
# store the new 2st place length and pathname
l[2] = currlen; p[2] = $0;
}
}
END {
for (i in l) printf "(%d) %d : %s\n", i, l[i], p[i];
}'
или с GNU awk (который поддерживает 2D массивы),
$ find $PWD -printf '%p\0' | gawk -v RS='\0' '
{
# get the length of the basename of the current filepath
n = split($0,a,"/");
currlen = length(a[n]);
if (currlen > p[1][1]) {
# bump the current longest to 2nd place
p[2][1] = p[1][1]; p[2][2] = p[1][2];
# store the new 1st place length and pathname
p[1][1] = currlen; p[1][2] = $0;
}
else if (currlen > p[2][1]) {
# store the new 2st place length and pathname
p[2][1] = currlen; p[2][2] = $0;
}
}
END {
for (i in p[1]) printf "(%d) %d : %s\n", i, p[i][1], p[i][2];
}'