3

Это, вероятно, довольно легко, но каков наилучший способ рекурсивного переименования всех каталогов с именем "A" в "B" ниже базового каталога без использования символических ссылок и объединения содержимого конфликтующих каталогов вместе? То есть, если каталог "B" уже существует, то содержимое "A" следует переместить в "B", а пустой каталог "A" удалить.

1 ответ1

0

Нет единой программы, которая выполняет функцию переименования / слияния, хотя mv ... -t ... было бы полезно, если бы ее было легче использовать в команде find . Итак, что я разработал:

find BaseDir/ -type d -name "A" | sort -r | while read d; \
     do [ -d "${d%A}B" ] && mv "$d"/* "${d%A}B"/ && rmdir "$d" || \
         mv "$d" "${d%A}B"; done

Что это делает:

  • Найти все каталоги с именем A
  • Выполните обратную сортировку, чтобы, например, BaseDir/A/A был переименован перед BaseDir/A: если последний был переименован первым, первый не будет найден впоследствии.
  • Пройдите по каждому найденному каталогу: если B не существует, работает простое переименование; в противном случае содержимое A перемещается в B и теперь пустое A можно удалить.

Обратите внимание, что если B уже существует, любые файлы, которые он содержит, будут перезаписаны файлами с таким же именем в A: вы можете добавить дополнительные команды, чтобы предотвратить это - вы можете использовать mv -i , но вам нужно будет восстановить терминал для любого запроса (например, mv </dev/stdin -i ... или что-нибудь, что поддерживает ваш Linux), так как stdin был перенаправлен в сценарий.

Я использовал кавычки, чтобы учесть пробелы в любом из элементов пути, включая A и B

Я пытался протестировать различные иерархии, но не уверен, что охватил все структуры, которые вы могли бы использовать. Я предлагаю сначала поставить echo перед командами mv и rmdir , пока вы не убедитесь, что команда делает то, что вам нужно.

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