Jakiej sekwencji poleceń mogę użyć do usunięcia katalogów, ale nie ich plików?

2

Jak usunąć katalogi, ale nie znajdujące się w nich pliki? Próbowałem następujące:

rm -di /Users/arthur/Desktop/MyFolder 

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

Jestem na komputerze Mac. BTW, chcę to zrobić automatycznie.

gadgetmo
źródło
Gdzie powinny iść pliki?
slhck,
@slhck w górę katalogu
gadgetmo

Odpowiedzi:

6

Metoda 1 - Najpierw przenieś, a następnie usuń

Po prostu przenieś pliki w górę o jeden katalog, a następnie usuń go. Pozwoli to zachować zawartą hierarchię plików / folderów.

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

Metoda 2 - Automatyzacja w funkcji powłoki

Możesz umieścić to w funkcji powłoki zdefiniowanej w ~/.bash_profile:

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

Jak powiedziano wcześniej, spowoduje to usunięcie tylko folderu nadrzędnego, pozostawiając nienaruszoną hierarchię dzieci.


Metoda 3 - Usuwanie rekurencyjne

Jeśli chcesz rekurencyjnie usunąć wszystkie foldery i po prostu zachować pliki w folderze, użyj następujących poleceń:

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
}

Pamiętaj, że to zastępuje pliki ze zduplikowanymi nazwami.


Metoda 4 - Usuwanie rekurencyjne ze zduplikowaną świadomością

Wreszcie, jeśli chcesz zachować duplikaty plików, możesz sprawdzić, czy już istnieją. W takim przypadku poprzedzimy je ciągiem liczb losowych. Oczywiście mogą istnieć znacznie bardziej wyrafinowane metody, ale widać, dokąd to zmierza.

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
}

Pętla findwyjścia jest wyjaśniona tutaj .

slhck
źródło
Dzięki. Czy można to zrobić rekurencyjnie?
gadgetmo
Masz na myśli, określ jeden katalog, a następnie wyeliminuj pełną hierarchię katalogów, zachowując tylko pliki? W takim przypadku zobacz moją zaktualizowaną odpowiedź.
slhck,
Dzięki, zaakceptowana odpowiedź. Ale co, jeśli mam taki katalog: wcześniej Jeśli uruchomię rmdr /Users/arthur/Desktop/MyFolder, zamienia się w to: po
gadgetmo
Jest to oczekiwane zachowanie, ponieważ wszystkie pliki zostaną przeniesione do tego samego katalogu docelowego. W Uniksie pliki o tej samej nazwie zostaną zastąpione przez mv. Pytanie brzmi: Czego oczekujesz jako wynik? Czy zduplikowane pliki powinny otrzymać inną nazwę?
slhck
Powinni dostać inną nazwę, jeśli to możliwe. Dzięki.
gadgetmo