Comment pouvez-vous déplacer (ou copier) tous les fichiers dans un répertoire avec le même préfixe de nom de fichier?

9

Utiliser Bash

Disons donc que j'ai un tas de fichiers placés au hasard dans un répertoire parent ~/src, je veux récupérer tous les fichiers correspondant à un certain suffixe et les déplacer (ou les copier) dans un ~/distrépertoire.

Supposons à cet effet que tous les noms de fichiers ont cette convention de dénomination:

<filename_prefix>.<filename_suffix>

J'ai découvert que c'était un moyen rapide d'obtenir tous les fichiers avec un particulier filename_suffixet de les mettre dans un dossier dist:

mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;

Maintenant, un pas de plus ... comment puis-je utiliser la sortie de find, dans ce cas filename, et utiliser le filename_prefixpour générer un répertoire du même nom ~/dist, puis déplacer (ou copier) tous les fichiers avec ce préfixe dans le répertoire approprié?

mkdir ~/dst
find source -name "*.xrt,*.ini,*.moo" -exec mv -i {} -t ~/dst \;

Essentiellement, comment puis-je changer la commande ci-dessus (ou peut-être utiliser une autre commande), pour créer une structure comme celle-ci

(PRODUCTION)

~/dist/people/people.xrt
~/dist/games/games.xrt
~/dist/games/games.moo
~/dist/games/games.ini
~/dist/monkeys/monkeys.ini
~/dist/monkeys/monkeys.xrt

à partir d'une arborescence de répertoires comme celle-ci?

(CONTRIBUTION)

~/src/xrt/people.xrt
~/src/xrt/games.xrt
~/src/conf/games.ini
~/src/pack/monkeys.xrt
~/src/e344/games.moo
~/src/e344/monkeys.moo
~/src/en-us/monkeys.ini
qodeninja
la source

Réponses:

10

Ce serait un enfer de dire findquoi faire dans ce cas.

Mieux utiliser la coque:

for i in **/*.{xrt,ini,moo}; do
  FILE=$(basename "$i")
  DIR=~/dst/${FILE%.*}
  echo mkdir -p -- "$DIR"
  echo mv -i -t "$DIR" -- "$i"
done

Utilisez shopt -s globstarpour faire fonctionner le **glob (ou utilisez zsh!). Et supprimez le echos plus tard si la commande imprime ce que vous voulez.

Stéphane Gimenez
la source
en utilisant bash est-ce la même chose?
qodeninja
@codeninja shopt -s globstar, voir ma modification. S'il n'y a que deux niveaux, vous pouvez utiliser */*.*et l'extrait de code fonctionnera dans n'importe quel shell.
Gilles 'SO- arrête d'être méchant'
2

tricher trouver la ligne de commande:

find source -name "*.xrt,*.ini,*.moo" -exec env file={} bash -c 'base="$(basename "$file")";dir="dst/${base%.*}";mkdir -p "$dir";cp "$file" "$dir"' \;

en fait une solution pour appeler le script bash dans find LOL.

= P

yuyichao
la source
1
Devinez ce qui se passe s'il y a un fichier qui s'appelle… happy rm -rf /! Ce type de code mérite un -1.
Stéphane Gimenez
Votre montage ne suffit pas: disons que vous avez cliqué sur un lien et téléchargé Yay" rm -rf / "Rox0r.avi, là encore il y a comme un problème…
Stéphane Gimenez
(Et il n'y a aucun moyen de sécuriser ce type de substitution).
Stéphane Gimenez
1
Ah peut-être qu'il est possible de faire ça différemment. Il semble que les travaux suivants: -exec bash -c 'command which uses "$1"' bash '{}' ';'. Eh bien, c'est tout à fait inutile de toute façon.
Stéphane Gimenez
1
@ StéphaneGimenez fait, bash n'est pas la seule chose à utiliser. LOL
yuyichao