Como tar os arquivos mais recentes com espaços no nome do arquivo?

3

Eu estou tentando criar um script que foreach directoy na pasta folder , apenas os arquivos n mais recentes devem ser compactados.

No entanto, estou tendo problemas com os vários arquivos de palavras. Eu preciso de uma maneira de envolvê-los em aspas, então o comando tar sabe qual é cada arquivo.

Aqui está o meu script até agora:

#!/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 
    
por dabadaba 06.04.2014 / 14:28

4 respostas

6

xargs para o resgate! Uma maneira é usar xargs para criar uma lista de argumentos, mas colocar cada arquivo dentro de aspas:

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

Outra opção é usar xargs para chamar diretamente tar no modo append ( -r ) e, em seguida, compactá-lo no final (você não pode criar arquivos compactados no modo append):

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

A vantagem da segunda abordagem é que você pode alterar 10 para qualquer outro, mesmo um número muito alto, e ele ainda funcionará sem ter uma lista de argumentos muito longa.

    
por Krzysztof Adamski 06.04.2014 / 15:35
1

Perl para o resgate:

#!/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 '..';
    }
}
    
por choroba 06.04.2014 / 14:59
1
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
    
por glenn jackman 06.04.2014 / 15:19
1

Você pode tentar:

#!/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 
    
por Radu Rădeanu 06.04.2014 / 15:12

Tags