
Ich habe Speicher in etwa wie unten auf AzureVM/Ubuntu
-/A
-/B --> 10000 log files
-/C --> 100000 log files
-/D --> 200000 images
summary.xml
-/data --> 1000 csv files
Da die Datenmenge zu groß für die Berechnung und für alle damit verbundenen Operationen ist, möchte ich eine Stichprobe dieser Daten entnehmen, um meinen Datenanalysecode zu entwickeln.
Ich möchte eine Teilmenge an einen anderen Speicherort kopieren, die die 100 neuesten Dateien in jedem Verzeichnis und verschachtelten Verzeichnis sowie alle Dateien im Stammverzeichnis enthält, ungefähr so.
-/New_Location
-/B --> 100 log files
-/C --> 100 log files
-/D --> 100 images
summary.xml
-/data --> 100 csv files
Ich habe mehrere auf cp basierende Befehle ausprobiert, aber nichts funktioniert und die Ausführung dauert zu lange.
Kann mir hier bitte jemand helfen?
Antwort1
Normalerweise kann man das in drei Aufgaben unterteilen, wobei man mit der Verzeichnisstruktur beginnt und dann, wie in Ihrem Fall, die Dateien auf 100 begrenzt. Der letzte Teil kehrt dieübereinstimmenum den Umfang der restlichen Dateien zu ermitteln.
#!/bin/bash
# Example START
[[ ! -d A/ ]] && { \
mkdir -p \
A/{tmp/folder,\
{A..Z}}/{images,data} && \
printf %s\\0 \
A/{summary.xml,\
tmp/De5Loh4X.tmp,\
{A..Z}/{{1..1000}_file.log,\
images/{1..1000}_pic.{jpg,png},\
data/example.csv}} | xargs -0 touch; }
### Example END
set -o noglob
source=A
target=target
number=100
# prune="-false"
prune="-type d -path $source/tmp -prune"
match='-name *.log -o -name *.jpg -o -name *.png'
echo Create directory structure.
find "$source" \
\( $prune -o -type d -links 2 \) -printf %P\\0 | cpio -0 -pvdm -D "$source" "$target"
echo Copy 100 files.
while IFS= read -rd ''; do
find "$REPLY" \
-maxdepth 1 -type f \( $match \) -printf '%T@\t%P\0' | sort -zk1rn | cut -zf2- | head -zn $number | cpio -0 -pvdm -D "$REPLY" "$target/${REPLY/#$source\//}"
done < <( \
find "$source" \
\( $prune -false -o -type f \) -printf %h\\0 | sort -zu \
)
echo Copy everything else.
find "$source" \
\( $prune -false -o -type f ! \( $match \) \) -printf %P\\0 | cpio -0 -pvdm -D "$source" "$target"
Antwort2
Dies lässt sich ganz einfach durch selektives Archivieren bewerkstelligen. Sie können die Dateien (nur die gewünschten) in ein Tarball-Archiv packen und das Tarball-Archiv dann woanders entpacken. Ich gehe davon aus, dass Ihre Protokolldateien bis auf die Nummerierung den gleichen Namen haben (z. B. log1, log2 usw.). Daher können die ersten hundert Dateien im Tarball-Befehl als log{1..100} definiert werden. Beispiel:
tar -cvf copied.tar <path1>/log{1..100} <path2>/log({1..100}
usw
Beim Extrahieren wird die ursprüngliche Dateistruktur am neuen Speicherort wiederhergestellt. Daher müssen Sie möglicherweise die Option „--strip-components=“ verwenden, um die redundanten führenden Verzeichnisse abzuschneiden und Unordnung zu vermeiden.