サブフォルダーを含む複数レベルの2 GBイメージを含むフォルダーがあります。
N
tarファイルに各(サブ)フォルダのファイルのみを保存したいと思います。find
その時使ってみましたが、うまくtail
いきtar
ませんでした。私が試したことは次のとおりです(仮説N = 10
)。
find . | tail -n 10 | tar -czvf backup.tar.gz
...このエラーを出力します。
Cannot stat: File name too long
どうなりますか?考えてみてください。動作していても、10個のファイルではなく、すべてのフォルダの最初の10個のファイルだけを圧縮すると思います。各フォルダ。
N
各フォルダのファイルを取得するには? (書類注文は不要)
答え1
pax
この-0
オプションをサポートしている場合は、以下を使用してくださいzsh
。
print -rN dir/**/*(D/e:'reply=($REPLY/*(ND^/[1,10]))':) |
pax -w0 | xz > file.tar.xz
これには、リスト内の各ディレクトリの最初の10個のディレクトリ以外のファイルがファイル名でソートされて含まれます。 glob修飾子を追加することで、別のソート順を選択できますom
。Om
oL
non
標準コマンドがないかpax
サポートされていないが-0
GNUコマンドがある場合は、tar
次のことができます。
print -rN -- dir/**/*(D/e:'reply=($REPLY/*(ND^/[1,10]))':) |
tar --null -T - -cjf file.tar.xz
その権限がないがzsh
アクセス権bash
(GNUプロジェクトのシェル)がある場合は、次のことができます。
find dir -type d -exec bash -O nullglob -O dotglob -c '
for dir do
set -- "$dir/*"; n=0
for file do
if [ ! -d "$file" ] || [ -L "$file" ]; then
printf "%s\0" "$file"
(( n++ < 10 )) || break
fi
done
done' bash {} + | pax -0w | xz > file.tar.xz
ただし、これにより効率が大幅に低下します。
答え2
/tmp/dir
各(サブ)フォルダのN(たとえば、N = 10)ファイルだけが単一のファイルに保存したいホームディレクトリがあるとしますbackup.tar.gz
。
例tree
:/tmp/dir
dir/
├── one
│ ├── one10.txt
│ ├── one11.txt
│ ├── one1.txt
│ ├── one2.txt
│ ├── one3.txt
│ ├── one4.txt
│ ├── one5.txt
│ ├── one6.txt
│ ├── one7.txt
│ ├── one8.txt
│ ├── one9.txt
│ └── one_deep
│ ├── one_deep1
│ ├── one_deep10
│ ├── one_deep11
│ ├── one_deep2
│ ├── one_deep3
│ ├── one_deep4
│ ├── one_deep5
│ ├── one_deep6
│ ├── one_deep7
│ ├── one_deep8
│ └── one_deep9
├── three
│ ├── three10.txt
│ ├── three11.txt
│ ├── three1.txt
│ ├── three2.txt
│ ├── three3.txt
│ ├── three4.txt
│ ├── three5.txt
│ ├── three6.txt
│ ├── three7.txt
│ ├── three8.txt
│ ├── three9.txt
│ └── three_deep
│ ├── three_deep1
│ ├── three_deep10
│ ├── three_deep11
│ ├── three_deep2
│ ├── three_deep3
│ ├── three_deep4
│ ├── three_deep5
│ ├── three_deep6
│ ├── three_deep7
│ ├── three_deep8
│ └── three_deep9
パスワード:
cd /tmp; for i in `find dir/* -type d`; do find $i -maxdepth 1 -type f | tail -n 10 | xargs -I file tar -rf backup.tar file; done; gzip backup.tar
backup.tar.gz
これにより、10個のファイルを含むサブフォルダが作成されます/tmp/dir
。
答え3
の出力はfind
単純なので、実際にパスを見ないと、どのファイルが同じディレクトリに属しているのかわかりません。別の方法は、find
パスをチェックせずに複数のs(各フォルダごとに1つ)を使用することです。これが私がすることです。サブフォルダごとに最大10個のファイルを圧縮するには、次のように使用します。
for dir in $(find . -type d); do
find "$dir" -maxdepth 1 -type f -printf "\"%p\"\n" | tail -10
done | xargs tar cvfz backup.tar.gz
現在のフォルダのすべてのディレクトリを再帰的に検索します。各ディレクトリに最大10個のファイルを見つけます。正確にフォルダ(-maxdepth 1
)。ループ全体が完了すると、tar
ループから出力されるすべてのファイルに対してコマンドが実行されます。また、対応するオプションを使用$dir
してfind
引用符で各ファイル名を印刷することで、スペースを含むディレクトリとフォルダ名を計算しました-printf
。
答え4
ディレクトリ名にハッシュを使用し、ハッシュ数がしきい値未満の場合にのみファイル名をエクスポートします。例えば
find . -depth -type f \
| perl -MFile::Spec -nle '(undef,$d,$f)=File::Spec->splitpath($_); print if $seen{$d}++ < 3' \
| tar ...