web-dev-qa-db-fra.com

Comment tarer les n fichiers les plus récents avec des espaces dans le nom du fichier?

J'essaye de créer un script qui foreach chacun dans le dossier folder, seuls les fichiers n les plus récents doivent être compressés.

Cependant, j'ai des problèmes avec les multiples fichiers Word. J'ai besoin d'un moyen de les envelopper entre guillemets afin que la commande tar sache ce qui est chaque fichier.

Voici mon script jusqu'à présent:

#!/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 
3
dabadaba

xargs à la rescousse! Une solution consiste à utiliser xargs pour créer une liste d'arguments, mais placez chaque fichier entre guillemets:

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

Une autre option consiste à utiliser xargs pour appeler directement tar en mode ajout (-r), puis en le compressant à la fin (vous ne pouvez pas créer d'archives compressées en mode ajout):

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

L’avantage de la deuxième approche est que vous pouvez remplacer 10 par n’importe quel autre nombre, même très élevé, et que cela fonctionnera toujours sans obtenir une liste d’arguments trop longue.

6

Perl à la rescousse:

#!/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 '..';
    }
}
1
choroba

Tu peux essayer:

#!/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 
1
Radu Rădeanu
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
1
glenn jackman