Определение длины файлов и пути к файлам в структуре каталогов в файловой системе Linux

Определение длины файлов и пути к файлам в структуре каталогов в файловой системе Linux

У меня возникла проблема в ОС Linux, работающей под управлением версии SMB, когда абсолютный путь к каталогу в общей папке равенбольше 1024 байт, а компонент имени файла больше 256 байтслужба SMB дает сбой и блокирует все остальные службы сетевого доступа, такие как SSH и FTP, из-за чего компьютер отключается.

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

Я пробовалнаходитьигрэпкоманды без успеха. Есть ли цепочка команд или скрипт, которые я могу использовать для поиска проблемных файлов и каталогов?

Пожалуйста, порекомендуйте.

решение1

Это написано на Bash и использует специфичные для него возможности (но похожие возможности доступны и в других оболочках). Он разработан для запуска из родительского каталога, общего для всех файлов и каталогов, которые вас интересуют. Он учитывает длину пути от /туда и добавляет ее к длине каждого оцененного пути. Если вы не хотите этого делать, просто используйте lenpwd=0вместо lenpwd=${#PWD}. Это будет работать, если есть файлы с пробелами в именах, но не те, в которых есть символы новой строки (которые должны быть изгнаны в любом случае). Он выводит длину и спецификацию файла всего, что он находит и что соответствует критериям.

lenpwd=${#PWD}; find | while read -r path; do file=${path##*/}; if (( ${#path} + lenpwd > 1024 || ${#file} > 256 )); then echo "$((${#path} + lenpwd)) ${#file} $path"; fi; done

решение2

Не знаю, правильно ли я вас понял, но первая попытка:

for f in $( find /srv/smb -type f )
do
  fname=$( basename "$f" )
  pname=$( dirname "$f" )

  l_fname=$( echo "$fname" | wc -c )
  l_pname=$( echo "$pname" | wc -c )

  if [ $l_fname -gt 256 ] ; then
    # do somthing with $f when filename > 256b
    rm -- "$f"
    continue
  fi

  if [ $l_pname -gt 1024 ] ; then
    # do something if path > 1024
    echo "$f much too long!"
  fi
done

Это просто я-не-тестировал-но-должен-работать-в-bash-и-equlas-shell-скрипте. Можете свободно добавлять проверку ошибок и другие полезные штуки...

решение3

Вот однострочный код, который выводит длину dirname, затем длину basename, затем dirname и, наконец, basename (для потомков). Я просто использовал текущий рабочий каталог, но это можно изменить. Это также можно расширить, чтобы вытащить значения, большие, чем ваши данные.

find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
 | awk '( NR%2 != 0){printf("%s ",$0);next}1 '
 | awk '{print length($1)" "length($2)" "$1$2}'

Обновлять:

Чтобы отсортировать по длине имени каталога, добавьте в конец следующее:

 | sort -nr

Чтобы отсортировать по длине базового имени, добавьте в конец следующее:

 | sort -nr -k2

Обновление 2:

По комментарию автора, это заменит пробелы на знаки «+», что позволит работать со счетчиками.

find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
 | tr '[:blank:]' '+'
 | awk '( NR%2 != 0){printf("%s ",$0);next}1 '
 | awk '{print length($1)" "length($2)" "$1$2}'

Связанный контент