web-dev-qa-db-ja.com

ファイルを検索し、それらをtar(スペースで)

わかりました、とても簡単な問題です。単純なバックアップコードを作成しています。ファイルにスペースが含まれている場合を除き、正常に機能します。これは私がファイルを見つけてtarアーカイブに追加する方法です:

find . -type f | xargs tar -czvf backup.tar.gz 

問題は、tarがフォルダーであると見なすため、ファイルの名前にスペースが含まれている場合です。基本的に、findの結果を引用符で囲む方法はありますか?または、これを修正する別の方法?

106
Caleb Kester

これを使って:

find . -type f -print0 | tar -czvf backup.tar.gz --null -T -

そうなる:

  • スペース、改行、先頭のダッシュなどの面白いファイルを扱う
  • 無制限の数のファイルを処理する
  • 多数のファイルがある場合にtar -cxargsと共に使用するのと同じように、backup.tar.gzを繰り返し上書きしません。

参照:

205
Steve Kehlet

あなたが望むものを達成する別の方法があるかもしれません。基本的に、

  1. findコマンドを使用して、探しているファイルへのパスを出力します。 stdoutを任意のファイル名にリダイレクトします。
  2. 次に、-Tオプションを指定してtarを実行すると、ファイルの場所(findで作成した場所)のリストを取得できます。

    find . -name "*.whatever" > yourListOfFiles
    tar -cvf yourfile.tar -T yourListOfFiles
    
14
errorprone

実行してみてください:

    find . -type f | xargs -d "\n" tar -czvf backup.tar.gz 
8
gsteff

何故なの:

tar czvf backup.tar.gz *

確かにfindを使用してからxargsを使用するのは賢明ですが、あなたは難しい方法でやっています。

更新:Porgesが、私の答えまたは他の答えよりも良い答えだと思うfind-optionでコメントしています:find -print0 ... | xargs -0 ....

7
Warren P

複数のファイルまたはディレクトリがあり、それらを独立した*.gzファイルに圧縮したい場合、これを行うことができます。オプション-type f -atime

find -name "httpd-log*.txt" -type f -mtime +1 -exec tar -vzcf {}.gz {} \;

これは圧縮されます

httpd-log01.txt
httpd-log02.txt

httpd-log01.txt.gz
httpd-log02.txt.gz
3
Kalibur x

このようなものを試してみませんか:tar cvf scala.tar `find src -name *.scala`

2
Frank Eggink

見られる別の解決策 here

find var/log/ -iname "anaconda.*" -exec tar -cvzf file.tar.gz {} +
2

@ Steve Kehlet post にコメントを追加しますが、50 rep(RIP)が必要です。

何度もグーグルでこの投稿を見つけた人には、時間範囲が指定された特定のファイルを見つけるだけでなく、tarringエラーを引き起こす相対パスORの空白も含めない方法を見つけました。 (ありがとうございますSO多くのスティーブ。)

find . -name "*.pdf" -type f -mtime 0 -printf "%f\0" | tar -czvf /dir/Zip.tar.gz --null -T -
  1. .相対ディレクトリ

  2. -name "*.pdf" pdf(または任意のファイルタイプ)を探します

  3. -type f検索するタイプはファイルです

  4. -mtime 0過去24時間以内に作成されたファイルを探す

  5. -printf "%f\0"通常-print0 OR -printf "%f"は機能しませんでした。マニュアルページから:

この引用は、GNU lsと同じ方法で実行されます。これは、-lsおよび-flsに使用されるものと同じ引用メカニズムではありません。 findの出力に使用する形式を決定できる場合は、ファイル名に空白や改行文字が含まれている可能性があるため、通常、改行を使用するよりもターミネータとして「\ 0」を使用する方が適切です。

  1. -czvfアーカイブの作成、gzipによるアーカイブのフィルタリング、処理されたファイルの詳細なリスト、アーカイブ名

編集2019-08-14:追加したいのですが、基本的にはtar自体を使用して、同じコマンドをコメントで使用することもできました:

tar -czvf /archiveDir/test.tar.gz --newer-mtime=0 --ignore-failed-read *.pdf

今日の新しいPDFがなかった場合に必要な--ignore-failed-read.

1
user3472383

最善の解決策は、ファイルリストを作成してからファイルをアーカイブすることです。他のソースを使用して、リストで何か他のことを行うことができるからです。

たとえば、これにより、リストを使用して、アーカイブされるファイルのサイズを計算できます。

#!/bin/sh

backupFileName="backup-big-$(date +"%Y%m%d-%H%M")"
backupRoot="/var/www"
backupOutPath=""

archivePath=$backupOutPath$backupFileName.tar.gz
listOfFilesPath=$backupOutPath$backupFileName.filelist

#
# Make a list of files/directories to archive
#
echo "" > $listOfFilesPath
echo "${backupRoot}/uploads" >> $listOfFilesPath
echo "${backupRoot}/extra/user/data" >> $listOfFilesPath
find "${backupRoot}/drupal_root/sites/" -name "files" -type d >> $listOfFilesPath

#
# Size calculation
#
sizeForProgress=`
cat $listOfFilesPath | while read nextFile;do
    if [ ! -z "$nextFile" ]; then
        du -sb "$nextFile"
    fi
done | awk '{size+=$1} END {print size}'
`

#
# Archive with progress
#
## simple with dump of all files currently archived
#tar -czvf $archivePath -T $listOfFilesPath
## progress bar
sizeForShow=$(($sizeForProgress/1024/1024))
echo -e "\nRunning backup [source files are $sizeForShow MiB]\n"
tar -cPp -T $listOfFilesPath | pv -s $sizeForProgress | gzip > $archivePath
1
Nux