Самое долгое имя файла в большом каталоге

В большом каталоге в моей системе Ubuntu (> 140 000 файлов и> 200 подкаталогов), я знаю, что где-нибудь существует два файла с именами слишком долго для копирования в папку Windows (NTFS). Я попробовал его и получил два сообщения об ошибках, но я не обращал внимание на то, в каких подпапках файлы были.

Как я могу найти эти два файла с самыми длинными именами?

3
задан 1 July 2017 в 01:34

2 ответа

Я предполагаю, что решением @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.

4
ответ дан 1 December 2019 в 13:23

На основе комментариев, в чем Вы действительно нуждаетесь в этом случае, список всех файлов, имена которых длиннее, чем некоторое максимальное количество символов - и к счастью это - относительно легкое использование 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];
  }'
3
ответ дан 1 December 2019 в 13:23

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

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