关于linux:查找文件并对它们进行tar(带空格)

Find files and tar them (with spaces)

好吧,这么简单的问题。我正在编写一个简单的备份代码。它工作得很好,除非文件中有空格。以下是我查找文件并将其添加到tar存档的方式:

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

问题是当文件名中有空间时,因为tar认为它是一个文件夹。基本上,有没有一种方法可以在find的结果周围添加引号?或者用另一种方法来解决这个问题?


使用此:

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

它将:

  • 处理带有空格、换行符、前导破折号和其他功能的文件
  • 处理无限数量的文件
  • 不会重复覆盖backup.tar.gz,就像在xargs中使用tar -c一样,当您有大量文件时会这样做。

还可以看到:

  • GNU沥青手册
  • 我怎样才能从stdin构建一个tar?,搜索空值


还有另一种方法可以实现你想要的。基本上,

  • 使用find命令将路径输出到您要查找的任何文件。将stdout重定向到您选择的文件名。
  • 然后使用-t选项tar,该选项允许它获取文件位置列表(使用find!创建的位置)。

    1
    2
    find . -name"*.whatever"> yourListOfFiles
    tar -cvf yourfile.tar -T yourListOfFiles

  • 试运行:

    1
    2
        find . -type f | xargs -d"
    " tar -czvf backup.tar.gz

    为什么不:

    1
    tar czvf backup.tar.gz *

    当然,先使用find,然后使用xargs是很聪明的,但这是很难做到的。

    更新:Porges评论说,我认为一个查找选项比我的答案更好,或者另一个:find -print0 ... | xargs -0 ....


    如果您有多个文件或目录,并且希望将它们压缩到独立的*.gz文件中,则可以执行此操作。可选-type f -atime

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

    这会压缩

    1
    2
    httpd-log01.txt
    httpd-log02.txt

    1
    2
    httpd-log01.txt.gz
    httpd-log02.txt.gz

    另一个解决方案如下所示:

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


    为什么不试试这样的东西:tar cvf scala.tar `find src -name *.scala`


    最好的解决方案似乎是创建一个文件列表,然后存档文件,因为您可以使用其他源并对该列表执行其他操作。

    例如,这允许使用列表计算正在存档的文件的大小:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #!/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"
    Running backup [source files are $sizeForShow MiB]
    "
    tar -cPp -T $listOfFilesPath | pv -s $sizeForProgress | gzip > $archivePath