2

Мне нужно создать список файлов для использования в сценарии оболочки. В списке должны быть все файлы (в указанном каталоге), которые имеют жесткую ссылку. Я хочу заменить жесткие ссылки символическими ссылками.

(Очевидно, я не могу удалить последнюю жесткую ссылку. И этот вопрос связан с другим вопросом, который имеет роковую ошибку.)

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

  • ищет в каталоге, который потенциально содержит жестко связанные файлы, чтобы сохранить
  • ищет другие жестко связанные файлы из каталога верхнего уровня или корня файловой системы
  • обе директории могут быть предоставлены в качестве параметров
  • может также работать только с файлами указанных типов (например, изображения)

Моя (новая) идея состоит в том, чтобы передать вывод этой find

find "$dir" -type f -links +1

В этот:

find "$topdir" -xdev -samefile <output from other find> -printf '%i:%p\n' | sort --field-separator=:

Если это сработает, то я предоставлю полученный список циклу while, похожему на этот (из исходного кода):

last_inode=
while IFS= read -r path_info
do
   inode=${path_info%%:*}
   path=${path_info##*:}
   if [[ $last_inode != $inode ]]; then
       printf "$inode\n"
       last_inode=$inode
       path_to_keep=$path
   else
       rm -- "$path"
       ln -s -- "$path_to_keep" "$path"
   fi
done

Я также могу добавить параметр (-iname "*.jpg" к (первой) команде поиска, который будет действовать только для файлов JPEG. (Я также открыт для лучших предложений здесь.)

1 ответ1

1

Вот решение, которое работает. Я проверил это довольно широко. Тем не менее, я приветствую лучшие ответы. Я предпочел бы выбрать чей-либо ответ, а не мой собственный (что говорит о моей уверенности в моих навыках написания сценариев в Bash).

find "$dir" -type f -links +1 -exec find "$topdir" -xdev -samefile '{}' -printf '%i:%p\n' \; | sort --field-separator=:

Вот полное решение, расширяющее связанный вопрос (при условии, что это работает):

#!/bin/bash
set -o nounset
topdir='/'
dir='/MotherBoards/Tyan S2720 Thunder i7500/IntelNetworkAdapterDrivers/Setup/'

echo "starting..."

# For each path which has multiple links
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# (except ones containing newline)
last_inode=
while IFS= read -r path_info
do
   inode=${path_info%%:*}
   path=${path_info##*:}
   if [[ $last_inode != $inode ]]; then
       printf "$inode\n"
       last_inode=$inode
       path_to_keep=$path
   else
       printf "$inode\tln -s\t'$path_to_keep'\t'$path'\n"
       rm -- "$path"
       ln -s -- "$path_to_keep" "$path"
   fi
done < <( find "$dir" -type f -links +1 -exec find "$topdir" -xdev -samefile '{}' -printf '%i:%p\n' \; | sort --field-separator=: )

# Warn about any excluded files
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
buf=$( find "$dir" -type f -links +1 -wholename '*
*' )
if [[ $buf != '' ]]; then
    echo 'Some files not processed because their paths contained newline(s):'$'\n'"$buf"
fi

echo "finished"
exit 0

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .