如何将文件名中带有空格的 n 个最新文件打包成 tar?

如何将文件名中带有空格的 n 个最新文件打包成 tar?

我正在尝试创建一个脚本,对folder文件夹中的每个目录都只n压缩最新的文件。

但是,我在处理多个 word 文件时遇到了麻烦。我需要一种方法将它们括在引号中,以便命令tar知道每个文件是什么。

到目前为止,这是我的脚本:

#!/bin/bash

if [ ! -d ~/backup ]; then
    mkdir ~/backup
fi

cd ~/folder
for i in *; do
    if [ -d "$i" ]; then
        original=`pwd`
        cd $i
        echo tar zcf ~/backup/"$i".tar.gz "`ls -t | head -10`"
        cd $original
    fi
done
echo "Backup copied in $HOME/backup/"
exit 0 

答案1

xargs来救场!一种方法是使用 xargs 创建参数列表,但将每个文件放在引号内:

echo `ls -t1 | head -10 | xargs -I'{}' echo \"{}\"`

其他选项是xargs直接以tar追加模式调用(-r),然后在最后进行压缩(您无法以追加模式创建压缩档案):

ls -t | head -10 | xargs -I'{}' tar -rvf ~/backup/"$i".tar '{}'
gzip ~/backup/"$i".tar

第二种方法的优点是,您可以更改10为任何其他数字,即使数字非常大,它仍然可以工作,而无需太长的参数列表。

答案2

Perl 来救援:

#!/usr/bin/perl
use warnings;
use strict;

my $backup = $ENV{HOME} . '/backup';
my $folder = $ENV{HOME} . '/folder';

-d $backup or mkdir $backup or die $!;
chdir $folder or die $!;
while (my $node = glob '*') {
    if (-d $node) {
        chdir $node;
        my @files = sort { -M $a <=> -M $b } glob '*';  # Sort files by age.
        @files = @files[0 .. 9] if @files > 10;         # Keep only the newest 10.
        system 'tar', 'zcf', "$backup/$node.tar.gz", @files;
        chdir '..';
    }
}

答案3

n=3
shopt -s nullglob
for dir in */; do
    cd "$dir"
    files=(*)
    if (( ${#files[@]} > 0 )); then
        files=()
        while IFS= read -r filename; do
            files+=("$filename")
        done < <( stat -c "%Y %n" * | sort -n | cut -d " " -f 2- | head -n $n )
        tar cf ../"${dir%/}.tar" "${files[@]}"
    fi
    cd - &>/dev/null
done

答案4

你可以试试:

#!/bin/bash

if [ ! -d $HOME/backup ]; then
    mkdir $HOME/backup
fi

cd $HOME/folder
for i in *; do
    if [ -d "$i" ]; then
        tar -cf $HOME/backup/"$i".tar -T /dev/null #create an empty, uncompressed, archive
        cd "$i"
        ls -t | head -10 | while read file; do
            tar -rf $HOME/backup/"$i".tar "$file" #append $file to archive
        done
        gzip $HOME/backup/"$i".tar # compress the archive
        cd $OLDPWD
    fi
done
echo "Backup copied in $HOME/backup/"
exit 0 

相关内容