В большой директории моей системы Ubuntu (> 140000 файлов и> 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.
Я думаю, что решение @ 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.
Я думаю, что решение @ 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.
Основываясь на комментариях, то, что вам действительно нужно в этом случае, это список всех файлов, имена которых длиннее некоторого максимального количества символов, и, к счастью, это относительно легко с использованием регулярного выражения find:
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];
}'
Основываясь на комментариях, то, что вам действительно нужно в этом случае, это список всех файлов, имена которых длиннее некоторого максимального количества символов, и, к счастью, это относительно легко с использованием регулярного выражения find:
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];
}'
Основываясь на комментариях, то, что вам действительно нужно в этом случае, это список всех файлов, имена которых длиннее некоторого максимального количества символов, и, к счастью, это относительно легко с использованием регулярного выражения find:
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];
}'