Яку послідовність команд можна використовувати для видалення каталогів, але не їх файлів?


2

Як видалити каталоги, але не файли всередині них? Я спробував таке:

rm -di /Users/arthur/Desktop/MyFolder 

remove /Users/arthur/Desktop/MyFolder? y
rm: /Users/arthur/Desktop/MyFolder: Directory not empty

Я на Mac. До речі, я хочу це зробити автоматично.


Куди мають піти файли?
slhck

@slhck до каталогу
gadgetmo

Відповіді:


6

Спосіб 1 - Спочатку переміщення, потім видалення

Просто перемістіть файли вгору по одній директорії та видаліть її. Це дозволить зберегти ієрархію файлів / папок.

mv ~/Desktop/MyFolder/* ~/Desktop/MyFolder/..
rmdir ~/Desktop/MyFolder

Спосіб 2 - Автоматизація функції оболонки

Ви можете помістити це в функцію оболонки, визначену у вашому ~/.bash_profile:

function rmd () {
  if [ -d "$1" ]; then
    mv "$1"/* "$1"/..
    rmdir "$1"
  else
    echo "$1 is not a directory"
  fi
}

Як було сказано раніше, це видалить лише батьківську папку, зберігаючи ієрархію дітей недоторканою.


Спосіб 3 - Рекурсивне видалення

Якщо ви хочете рекурсивно видаляти всі папки та просто зберігати файли, що містяться, скористайтеся наступним:

function rmdr () {
  if [ -d "$1" ]; then
    p="$1"/..
    find "$1" -type f -exec mv '{}' "$p" \;
    rm -rf "$1"
  else
    echo "$1 is not a directory"
  fi
}

Зауважте, що це перезаписує файли з повторюваними іменами.


Спосіб 4 - Рекурсивне видалення з дублюванням дублікатів

Нарешті, якщо ви хочете зберегти дублікати файлів, ви можете перевірити, чи вони вже існують. У цьому випадку ми додамо їх до довільного рядка чисел. Звичайно, можуть бути і більш складні методи, ніж це, але ви можете бачити, куди це йде.

function rmdr () {
  if [ -d "$1" ]; then
    p="$1"/..
    # loop through all files
    while IFS= read -r -d '' file; do
      filename=$(basename "$file")
      # if it already exists, prefix with random number
      if [ -f "$p/$filename" ]; then
        mv "$file" "$p/$RANDOM-$filename"
      # if it doesn't exist, just move
      else
        mv "$file" "$p"
      fi
    done < <(find "$1" -type f -print0)
    # remove parent directory
    rm -rf "$1"
  else
    echo "$1 is not a directory"
  fi
}

Прокручування findрезультатів пояснюється тут .


Дякую. Чи можна це робити рекурсивно?
гаджетмо

Ви маєте на увазі вказати один каталог, а потім усунути повну ієрархію каталогів, просто зберігаючи файли? У такому випадку дивіться мою оновлену відповідь.
slhck

Дякую, прийняту відповідь. Але що робити, якщо у мене є такий каталог: раніше Якщо я запускаю rmdr /Users/arthur/Desktop/MyFolder, він перетворюється на
наступне

Це очікувана поведінка, оскільки всі файли будуть переміщені в один і той же цільовий каталог. У Unix файли з тим самим іменем будуть перезаписані mv. Питання: Що ви очікуєте на виході? Чи повинні дублікати файлів отримати інше ім’я?
slhck

Вони повинні отримати іншу назву, якщо це можливо. Дякую.
гаджетмо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.