Linux | Kopiere nur die 100 wichtigsten neuen Dateien im Verzeichnis und in verschachtelten Verzeichnissen

Linux | Kopiere nur die 100 wichtigsten neuen Dateien im Verzeichnis und in verschachtelten Verzeichnissen

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.

verwandte Informationen