
AzureVM/Ubuntuに以下のようなストレージがあります
-/A
-/B --> 10000 log files
-/C --> 100000 log files
-/D --> 200000 images
summary.xml
-/data --> 1000 csv files
データのサイズが非常に大きいため、計算したり操作を実行したりできないため、このデータのサンプルを取得してデータ分析コードを開発したいと考えています。
各ディレクトリとネストされたディレクトリ内の最新の 100 個のファイルと、ルート上のすべてのファイルを含むサブセットを別の場所にコピーしたいと考えています。
-/New_Location
-/B --> 100 log files
-/C --> 100 log files
-/D --> 100 images
summary.xml
-/data --> 100 csv files
cp に基づく複数のコマンドを試しましたが、何も機能せず、実行に時間がかかりすぎます。
誰か私を助けてくれませんか?
答え1
通常、これを3つのタスクに分けることができます。まずディレクトリ構造から始め、次に、あなたのケースのように、ファイルを100個に制限します。最後の部分は、マッチ残りのファイルの範囲を確認します。
#!/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"
答え2
これは、選択的なアーカイブによって簡単に実行できます。ファイル (目的のもののみ) を tarball にまとめ、その tarball を別の場所に展開します。ログ ファイルは番号を除いて同じ名前 (例: log1、log2 など) であると想定しています。したがって、最初の 100 個のファイルは、tarball コマンドで log{1..100} として定義できます。例:
tar -cvf copied.tar <path1>/log{1..100} <path2>/log({1..100}
等
抽出すると、元のファイル構造が新しい場所に再作成されます。そのため、混乱を避けるために、冗長な先頭ディレクトリを切り捨てる「--strip-components=」オプションを使用する必要がある場合があります。