Это, вероятно, довольно легко, но каков наилучший способ рекурсивного переименования всех каталогов с именем "A" в "B" ниже базового каталога без использования символических ссылок и объединения содержимого конфликтующих каталогов вместе? То есть, если каталог "B" уже существует, то содержимое "A" следует переместить в "B", а пустой каталог "A" удалить.
1 ответ
Нет единой программы, которая выполняет функцию переименования / слияния, хотя 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 , пока вы не убедитесь, что команда делает то, что вам нужно.
