web-dev-qa-db-fra.com

Utiliser xargs pour mv un répertoire à partir de la recherche de résultats dans un autre répertoire

J'ai la commande suivante: 

find . -type d -mtime 0 -exec mv {} /path/to/target-dir \;

Cela déplacera le répertoire trouvé vers un autre répertoire. Comment puis-je utiliser xargs au lieu de exec pour faire la même chose.

30
zjhui

Si vous avez GNU mv (et find et xargs), vous pouvez utiliser l'option -t pour mv (et -print0 pour find et -0 pour xargs):

find . -type d -mtime -0 -print0 | xargs -0 mv -t /path/to/target-dir

Notez que les versions modernes de find (compatible avec POSIX 2008) prennent en charge + à la place de ; et se comportent à peu près comme xargs sans utiliser xargs:

find . -type d -mtime -0 -exec mv -t /path/to/target-dir {} +

Cela fait du groupe find des numéros pratiques de noms de fichiers (répertoires) en un seul appel du programme. Vous n'avez pas le niveau de contrôle sur le nombre d'arguments passés à mv que xargs fournit, mais vous en avez rarement besoin de toute façon. Cela dépend toujours de l'option -t de GNU mv.

39
Jonathan Leffler

Avec BSD xargs (pour OS X et FreeBSD), vous pouvez utiliser -J qui a été construit pour cela:

find . -name some_pattern -print0 | xargs -0 -J % mv % target_location

Cela déplacerait tout ce qui correspond some_pattern dans . à target_location

Avec GNU xargs (pour Linux et Cygwin), utilisez plutôt -I:

find . -name some_pattern -print0 | xargs -0 -I % mv % target_location

L'option obsolète -i de GNU xargs implique -I{} et peut être utilisée comme suit:

find . -name some_pattern -print0 | xargs -0 -i mv {} target_location

Notez que BSD xargs a également une option -I, mais cela fait autre chose.

38
user974202
find ./ -maxdepth 1 -name "some-dir" -type d -print0 | xargs -0r mv -t x/

find : avec l'option -print0, la sortie se terminera par '\ 0';

xargs : avec l'option -0, les arguments seront divisés par '\ 0', mais l'espace, -r signifie no-run-if-empty, vous n'aurez donc aucune erreur si find n'a pas généré de sortie . (Le -r est une extension GNU.)

J'utilise généralement cela dans les scripts lorsque je ne suis pas sûr que les fichiers cibles existent ou non.

3
Evans Y.

find n'est pas vraiment un bon outil pour cela. J'imagine que vous souhaitez déplacer tous les sous-répertoires dans un autre répertoire. find affichera des choses comme

./a
./a/b
./a/b/c
./a/b/c/d

Une fois que ./a est déplacé en premier, vous obtiendrez simplement des erreurs à propos de "aucun fichier ou répertoire" de tous les sous-répertoires.

Vous devriez simplement utiliser mv */ /another/place - la barre oblique à la fin du caractère générique limite l'expansion aux seuls répertoires.

2
glenn jackman

Si vous n'utilisez pas GNU mv, vous pouvez utiliser cette commande: 

find . -depth -type d -mtime 0 -exec bash -c 'declare -a array;j=1;for i; do array[$j]="$i"; j=$((j+1));done; mv "${array[*]}" /path/to/target-dir' arg0 {} +

sinon, voici une solution plus simple qui ne nécessite pas xargs:

find . -depth -type d -mtime 0 -exec mv -t /path/to/target-dir {} +

Notez que j'ai ajouté -depth sinon vous aurez des erreurs quand un répertoire et un de ses sous-répertoires doivent être traités.

0
jlliagre