Как удалить промежуточные папки, каждая из которых содержит только одну папку?

Я играл с mv, и теперь у меня ситуация. Раньше, скажем, в Folder1 был файл1,2,3.

Теперь у Folder1 есть Folder2, у которого есть Folder3, у которого есть Folder4, который содержит file1,2,3.

Я пытаюсь написать сценарий bash таким образом, чтобы он определял промежуточные папки, содержащие только 1 каталог, и перемещал все его содержимое на один уровень вверх, в конечном итоге возвращая только Folder1-> file1,2,3, а остальные удаленные папки.

Я пытался написать что-то вроде ниже, но я:

1. невозможно различить файл и папку

2. не удается найти имя файла / каталога, хранящегося в текущей папке

3. Не знаю, как делать рекурсивно.

#!/bin/bash

echo "Directory Name?"
read dir_name

no_files=`ls -A| wc -l`

if [ $no_file==1 ] && [ itisaDirectory()];
then `mv folder_name/* dir_name`
fi

person viv1    schedule 12.09.2015    source источник
comment
Подсказка: [ -d "$file" ] будет истинным, если $file - это каталог.   -  person tripleee    schedule 12.09.2015
comment
Ваш код уже содержит синтаксические ошибки; исправления см. на shellcheck.net. (Однако он не предупреждает о дурацких обратных кавычках вокруг команды mv.)   -  person tripleee    schedule 12.09.2015


Ответы (1)


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

find . -type f -exec mv {} "${dir_name}" \; 2>/dev/null
rm -r */

Вы просите чего-то другого, перемещайте только файлы, в которых промежуточный каталог уникален. Это так, если ровно один подкаталог имеет этот каталог в качестве родительского. Родителя каталога можно найти с помощью dirname. Когда каталог имеет один подкаталог, только один подкаталог будет иметь его в качестве родительского. Вы можете перечислить все каталоги, найти родителя и выбрать уникальные пути.

find . -type d  -exec dirname {} \; | sort | uniq -u | while read dir; do
   echo "${dir} has exactly one subdir"
done

Проблема в том, что в каталоге тоже могут быть файлы. Мы пытаемся улучшить вышеуказанное решение:

find . -exec dirname {} \; | sort | uniq -u | while read dir; do
   echo "${dir} has exactly one subdir or one file"
done

Вы можете проверить содержимое каталога с помощью if [ -d "${dir}/*" ], но мне не нужно знать:

find . -exec dirname {} \; | sort | uniq -u | while read dir; do
   echo "${dir} has exactly one subdir or one file"
   find "${dir}"/*/ -type f -exec mv {} "${dir_name}" \; 2>/dev/null
done

Путь $ {dir} / * / будет существовать только тогда, когда $ {dir} имеет подкаталог в нем, и будет перемещать файлы ниже. Когда в $ dir есть только один файл, команда find ничего не найдет.

person Walter A    schedule 12.09.2015