Verzeichnisstruktur mit beliebiger Anzahl von Dateien kopieren

Verzeichnisstruktur mit beliebiger Anzahl von Dateien kopieren

Gibt es eine elegante und schnelle Möglichkeit, eine bestimmte Verzeichnisstruktur zu kopieren und dabei nur eine zufällige Anzahl von Dateien auszuwählen, die mit kopiert werden sollen? So haben Sie beispielsweise die Struktur:

--MainDir
  --SubDir1
    --SubSubDir1
      --file1
      --file2
      --...
      --fileN
    --...
    --SubSubDirN
      --file1
      --file2
      --...
      --fileN
  --...

Ich möchte die gesamte Ordnerstruktur kopieren, aber nur eine bestimmte Anzahl zufälliger Dateien aus {files1-filesN} jedes SubSubDir zum Mitkopieren auswählen.

Antwort1

Da Sie dies als solches markiert haben, linuxgehe ich davon aus, dass es sich um GNU-Dienstprogramme handelt.

Verzeichnisstruktur kopieren von $srcnach $dest:

find "$src" -type d -print0 | cpio -padmv0 "$dest"

Kopieren Sie außerdem eine zufällige Auswahl von $nfileDateien aus jedem Blattunterverzeichnis von $src:

find "$src" -type d -links 2 -exec \
    sh -c 'find "$1" -type f -print0 | shuf -z -n "$2"' sh {} "$nfiles" \; | \
    cpio -padmv0  "$dest"

Hier findfindet der erste Befehl die Blattunterverzeichnisse ( -links 2), dann findfindet der zweite Befehl die Dateien in jedem dieser Unterverzeichnisse. shufEr wählt eine zufällige Auswahl von Dateien aus und cpiokopiert sie schließlich.

Antwort2

Suchen Sie zuerst alle Verzeichnisse:

find MainDir -type d

Dann analysieren Sie diese Verzeichnisse in ein Skript

find MainDir -type d -exec ./randomCopy.sh 2 {} \;

, welche

  1. Erstellt das Zielverzeichnis
  2. Kopiert eine zufällige Anzahl von Dateien.

In diesem Fall werden 2 zufällige Dateien kopiert.

In meinem Beispiel sieht das Skript randomCopy.shfolgendermaßen aus:

#!/bin/bash                                                                                                                                                                                                                                                                    
cnt="$1"                                                                                                                                                                                                                                                                     
dir="$2"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
mkdir -p "TARGET/$dir"                                                                                                                                                                                                                                                       

# see: https://stackoverflow.com/questions/414164/how-can-i-select-random-files-from-a-directory-in-bash                                                                                                                                                                     
find "$dir" -maxdepth 1 -type f | sort -R | tail -n $cnt | while read file; do                                                                                                                                                                                               
  # copy the file                                                                                                                                                                                                                                                            
  cp "$file" "TARGET/$dir/"
done

Und vergessen Sie nicht, das Skript ausführbar zu machen: chmod +x randomCopy.sh.

Ersetzen Sie die Zeichenfolge TARGETdurch Ihr Zielverzeichnis oder verwenden Sie eine dritte Skriptoption.

Dieser Proof of Concept läuft in meinem Testverzeichnis, es besteht jedoch möglicherweise noch erheblicher Verbesserungsbedarf.

verwandte Informationen