web-dev-qa-db-fra.com

Copier / Coller le code de la boucle

Je suis nouveau dans Linux alors voici ma question très fondamentale. J'ai un répertoire avec 41 dossiers. Je dois créer une boucle pour que le processus aille dans chaque dossier, copier tous les fichiers, puis tout coller dans un dossier spécifique.

Une idée comment aborder cela? Ce serait beaucoup de cliquer sans solution de code

Dans l'image, vous pouvez voir tous les dossiers auxquels j'ai besoin d'accéder et le dossier de sortie où je veux tout coller (zPASTE_EVERYTHING_HERE)

Directory

Mon chemin est: /shared/home/data/output

Voudrais tout coller dans: /shared/home/data/output/zPASTE_EVERYTHING_HERE

4
GCGM

En admettant que:

  • Les dossiers à copier et leurs fichiers sont sous /home/gcgm/myfolders
  • Le dossier de sortie est /tmp/output-folder

Si vous devez copier tous les fichiers dans un autre dossier, vous pouvez procéder comme suit:

mkdir /tmp/output-folder
cd /home/gcgm/myfolders
cp */* /tmp/output-folder

La signification de */* in the this commandcp / target` est:

  • Prenez tous les fichiers (le 2e *) dans tous les répertoires (le premier *) situés dans le répertoire actuel.
5
Yaron

Selon votre exemple, votre répertoire de destination ne contient aucun chiffre, contrairement à tous vos répertoires sources. Ainsi, vous pouvez simplement utiliser (GNU) cp comme ci-dessous à partir du répertoire parent, dans bash:

shopt -s dotglob  #Enables matching hidden files with glob patterns
shopt -s globstar #Enables recursive traverse of directories
cp -t zPASTE_EVERYTHING_HERE *[[:digit:]]*/**/*
  • cp fait la copie
  • -t zPASTE_EVERYTHING_HERE définit le répertoire de destination
  • *[[:digit:]]*/**/* correspond aux répertoires contenant au moins un chiffre, les traverse (à n'importe quelle profondeur) et obtient tout.

Faire tout dans un sous-shell pour garder le Shell parent intact; du répertoire parent:

( shopt -s dotglob && shopt -s globstar && \
    cp -t zPASTE_EVERYTHING_HERE *[[:digit:]]*/**/* )

Maintenant, pour tout nom de répertoire de destination aléatoire, définissez le répertoire comme suit: GLOBIGNORE variable:

GLOBIGNORE=whatever_destination

Maintenant, vous pouvez simplement faire:

cp -t whatever_destination */**/*

ou vous pouvez utiliser extglob:

shopt -s extglob #Should be already set on any interactive Shell session
cp -t whatever_destination !(whatever_destination)/**/*

Note complémentaire:

Il est possible que ARG_MAX soit déclenché si vous avez plusieurs fichiers/répertoires dans les répertoires source. Dans ce cas, vous avez deux options:

  • Utilisez une construction for pour parcourir les fichiers un par un, ce serait très lent, comme vous pouvez l'imaginer:

    for f in !(whatever_destination)/**/*; do cp -- "$f" whatever_destination/; done
    
  • Utilisez find:

    find . -mindepth 1 -maxdepth 1 -type d -not -name whatever_destination \
        -name '*' -exec sh -c 'cp -rt whatever_destination "$1"/*' _ {} \;
    
6
heemayl