2010-03-27 4 views
3

je la structure de répertoire suivant:Adjonction plutôt que d'écraser des fichiers lors du déplacement

+-archive 
    +-a 
    +-data.txt 
    +-b 
    +-data.txt 
+-incoming 
    +-a 
    +-data.txt 
    +-c 
    +-data.txt 

Comment puis-je faire l'équivalent de mv incoming/* archive/ mais ont le contenu des fichiers dans incoming annexés à ceux archive plutôt que de les écraser ?

+3

Bonjour, ukas1, bienvenue à StackOverflow. C'est agréable de voir quelqu'un utiliser la syntaxe markdown correctement dans sa première question. – Boldewyn

Répondre

2
# move to incoming/ so that we don't 
# need to strip a path prefix 
cd incoming 

# create directories that are missing in archive 
for d in `find . -type d`; do 
    if [ ! -d "../archive/$d" ]; then 
    mkdir -p "../archive/$d" 
    fi 
done 

# concatenate all files to already existing 
# ones (or automatically create them) 
for f in `find . -type f`; do 
    cat "$f" >> "../archive/$f" 
done 

Cela devrait trouver un fichier dans incoming et concaténer à un fichier existant dans archive.

L'important est d'être à l'intérieur incoming, car sinon nous aurions dû dépouiller le préfixe de chemin (ce qui est possible, mais pas nécessaire dans le cas ci-dessus). Dans le cas ci-dessus, une valeur de $f ressemble typiquement à ./a/data.txt, et par conséquent la redirection passe à ../archive/./a/data.txt.

+0

Merci pour la réponse (et l'accueil). Il fait exactement ce que je cherchais. – user303163

0

Voici une version avec une bonne citation:

#!/bin/sh 
if [ -z "$1" ]; then 
    # acting as parent script 
    find incoming -type f -exec "$0" {} \; 
else 
    # acting as child script 
    for in_file; do 
     if [ -f "$in_file" ]; then 
      destfile="${in_file/incoming/archive}" 
      test -d "$(dirname "$destfile")" || mkdir -p "$_" 
      cat "$in_file" >> "$destfile" && 
      rm -f "$in_file" 
     fi 
    done 
fi 
+0

Le problème est que 'basename' est trop petit. À l'intérieur des entrées et des archives, il semble y avoir une structure de répertoires importante. – Boldewyn

+0

@Boldewyn - Reconnu et corrigé. Maintenant, il utilise le remplacement de regex de Bash. – amphetamachine

+0

Vous ne définissez pas 'in_file' n'importe où et il manque un signe dollar dans l'instruction for. –

0

exécuter sur le répertoire courant.

find ./incoming -type f | while read -r FILE 
do 
    dest=${FILE/incoming/archive} 
    cat "$FILE" >> "$dest" 
done 

celui incoming/c ne serait pas ajouté que

Questions connexes