Bash: условно перемещенные вложенные дубликаты каталогов

0

Предположим, у меня есть каталог с именем "foo", который содержит несколько каталогов:

foo/bar/bar/(files)
foo/bat/bat/(files)
foo/baz/qux/(files)

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

Желаемый вывод:

foo/bar/(files)
foo/bat/(files)
foo/baz/qux/(files)
user259743
источник

Ответы:

0

Вы можете использовать find:

find . -regextype posix-awk -type d -regex ".*/(.*)/\1$" -exec sh -c "mv {}/* {}/../" \; -delete
  • -regextype posix-awk: нам нужно использовать posix-awkregextype, чтобы использовать обратную ссылку ( \1)
  • -type d: целевые каталоги
  • -regex ".*/(.*)/\1$": целевые файлы, соответствующие */bar/bar
  • -exec sh -c "mv {}/* {}/../": перемещает целевые каталоги в родительские каталоги
  • -delete: удаляет целевые каталоги

Примечание: вы не можете использовать rmdir {}внутри -exec( findвернет No such file or directoryошибку), вам нужно использовать -deleteопцию после -exec.

ssssteffff
источник
0

Непроверенные:

DIR=foo
ls $DIR | while read SUBDIR ; do
  [ -d $DIR/$SUBDIR/$SUBDIR ] || continue
  mv $DIR/$SUBDIR/$SUBDIR/* $DIR/$SUBDIR/
  rmdir $DIR/$SUBDIR/$SUBDIR
done
Феликс Франк
источник