Déplacer un groupe de fichiers, invitant l'utilisateur à confirmer chaque fichier

9

Système: Ubuntu MATE 18.04.

J'ai une collection de fichiers (dans plusieurs répertoires dans une structure de répertoires) et je veux en déplacer plusieurs dans un autre répertoire. Je peux dire quels fichiers je veux déplacer par leurs noms (ce sont des titres de recettes), mais il n'y a pas d'autre moyen de distinguer entre les fichiers que je veux déplacer et les fichiers que je ne veux pas déplacer; Je dois prendre une décision pour chaque dossier en examinant moi-même le nom.

Donc, je lance une commande une fois pour chaque fichier que je veux déplacer, comme

mv Snacks/OkaraCrackers NeedsTesting/
mv Snacks/SunflowerBrittle NeedsTesting/
mv Treats/ChocolateChilliFudge NeedsTesting/
mv Treats/PecanBlondies NeedsTesting/

Même avec la tabulation terminée, c'est trop de frappe. Ce que je veux vraiment faire, c'est quelque chose comme

shopt -s globstar
mv --prompt-me-for-every-file ** NeedsTesting/

Je peux donc simplement appuyer sur you npour chaque fichier.

Comment déplacer un groupe de fichiers et être invité à confirmer chaque fichier?

Zanna
la source

Réponses:

6

Méthode 1: dans votre navigateur de fichiers graphiques, à l'aide d'une arborescence

Je suppose que votre objectif réel est de faire un choix pour chaque fichier, et non à proprement parler d'être invité . Cependant, si vous préférez être invité à propos de chaque fichier dans un terminal, consultez la méthode 2 ci-dessous.

La plupart des navigateurs de fichiers graphiques prennent en charge une arborescence dans laquelle vous pouvez afficher plusieurs niveaux d'une hiérarchie de répertoires ensemble. Vous pouvez copier ou déplacer des fichiers hors de cette vue, soit individuellement, soit en les sélectionnant, puis en opérant sur l'ensemble de la sélection. Cela fonctionne même avec des fichiers provenant de plusieurs dossiers.

Dans certains navigateurs de fichiers, il faut aller dans un menu Préférences pour activer l'arborescence. Dans Caja, le navigateur de fichiers MATE, il est toujours activé dans la vue de liste. Cliquez sur Affichage → Liste (ou appuyez sur Ctrl+ 2) pour passer à l'affichage de la liste. Chaque répertoire a un petit triangle orienté vers la droite à gauche de celui-ci, indiquant qu'il peut être développé. Pour développer un dossier, cliquez sur ce triangle ou appuyez sur la touche (flèche droite) lorsque le dossier est sélectionné. Dans cet exemple, je les ai tous sélectionnés un par un et je les fais tous glisser en même temps vers leur destination:

plusieurs fichiers sélectionnés dans une arborescence dans le navigateur de fichiers Caja, étant glissés dans un autre dossier mais pas encore déplacés

En supposant que la source et la destination se trouvent sur le même lecteur, les déplacements par glisser-déplacer par défaut. Si vous souhaitez copier à la place, vous devez maintenir la Ctrltouche enfoncée.

la situation après la fin du glisser-déplacer, dans laquelle les fichiers sélectionnés sont maintenant tous ensemble dans le dossier de destination au lieu de leurs emplacements distincts d'origine

En théorie, il est facile de corriger les erreurs lors de l'utilisation de cette méthode, car la plupart des navigateurs de fichiers (y compris Caja) prennent en charge Ctrl+ Zpour annuler les actions récentes, y compris les actions par lots. Cependant, j'ai eu une chance mitigée avec cela. Parfois, les fichiers retournent dans le mauvais dossier.

La bonne nouvelle est que vous semblez travailler principalement avec des documents texte, qui ont tendance à être petits, vous pouvez donc effectuer une sauvegarde supplémentaire en tarpremier sans trop de tracas. Je suggère de le faire quelle que soit la méthode que vous utilisez.

Voie 2 : La findcommande avec l' -okaction

Il est courant findde rechercher des fichiers et de passer leurs chemins d'accès à une commande externe arbitraire avec les actions -execet -execdir. Mais a findégalement -oket -okdircette invite avant chaque fois qu'ils exécutent une commande. Si vous voulez vraiment être invité dans un terminal à propos de chaque fichier, je pense que c'est la voie à suivre.

Une fois terminé pour produire les mêmes effets que ceux indiqués ci-dessus, cela ressemble à ceci:

ek@Gnar:~$ find Texts -xtype f -ok mv -t 'Glorious Destination Folder' {} \;
< mv ... Texts/Robert Frost/New Hampshire.pdf > ? y
< mv ... Texts/Robert Frost/In The Clearing.pdf > ? n
< mv ... Texts/Helen Keller/The Story of My Life.pdf > ? y
< mv ... Texts/Saki/The Short Stories of Saki.pdf > ? y
< mv ... Texts/Jane Austen/Sense and Sensibility.pdf > ? n
< mv ... Texts/Jane Austen/Pride and Prejudice.pdf > ? y
< mv ... Texts/Richard Connell/The Stolen Crime.pdf > ? n
< mv ... Texts/Richard Connell/The Most Dangerous Game.txt > ? y
< mv ... Texts/Mary Wollstonecraft Shelley/Mathilda.epub > ? n
< mv ... Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf > ? y
< mv ... Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf > ? n
< mv ... Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm > ? y

Remplacez-le Textspar le répertoire source (qui pourrait l'être .si vous y êtes cd) et Glorious Destination Folderpar le répertoire de destination réel.

Cela exécute une commande par fichier; contrairement à -execet -execdir, -oket -okdirne prend pas en charge +à la place de \;passer plusieurs chemins trouvés dans le même appel d'une commande. Par conséquent, vous n'avez pas besoin d'utiliser le -t destformulaire de mv. Je suggère de faire de toute façon, même si, à la fois en général avec findet en particulier dans cette situation afin que les invites ressemblent plus aux commandes , ils sont de questions portant sur.

Au fur et à mesure que cette commande est écrite, si findrencontre un lien symbolique qui pointe finalement vers un fichier normal, il (le lien, pas la cible) est déplacé plutôt qu'ignoré. Si vous voulez vraiment utiliser un seul fichier normal, utilisez -type fplutôt que -xtype f.

Vous voudrez peut-être le faire dans une scriptsession afin que vous puissiez comprendre ce qui s'est passé si vous faites une erreur. Mais encore une fois, aucune raison de ne pas avoir de sauvegarde.

Méthode 3: Générez un manifeste et modifiez-le

Au moins tant que les fichiers n'ont pas de retour à la ligne dans leurs noms, vous pouvez commencer par utiliser une simple findcommande pour générer un fichier manifeste - un fichier qui répertorie les noms des fichiers qui vous intéressent (dans ce cas, potentiellement). :

find Texts -xtype f >manifest

Remplacez manifestpar le nom de votre choix pour le fichier qui répertorie les fichiers à l'étude (et ajustez les autres directions en conséquence).

Comme ci-dessus, remplacez-le Textspar votre répertoire source réel, ce qui pourrait être le .cas si vous l'aviez cdfait. Cependant, s'il Textss'agit d'un chemin relatif (y compris s'il l'est .), vous devez vous assurer d'être au même endroit plus tard lorsque vous effectuez réellement les mouvements.

Après avoir exécuté cette findcommande, ouvrez-le manifestdans un éditeur de texte. Cela pourrait être nano, vim, emacs, gedit, pluma, etc. Dans l'éditeur, commentaires sur les lignes nom fichiers ne souhaitez déplacer en plaçant un #au début d'entre eux. Certains éditeurs mettront ces lignes en surbrillance différemment même s'il ne reconnaît pas que votre fichier est dans un format dont il sait qu'il comporte des commentaires. La plupart ne le feront pas, cependant, et la vraie raison pour laquelle je suggère de le faire de cette façon est que vous, en tant qu'humain, avez probablement de l'expérience dans les commentaires des lignes dans les fichiers de configuration (et peut-être dans le code source). Je pense que cela est plus intuitive et moins sujette aux erreurs, qu'il serait de marquer les lignes que vous ne souhaitez déplacer.

Bien sûr, vous pouvez simplement supprimer les lignes des fichiers que vous ne souhaitez pas déplacer. L'avantage de les commenter est qu'il sera clair plus tard ce que vous avez fait.

Dans mon exemple, voici à quoi ressemblait le contenu du fichier après l'avoir modifié:

Texts/Robert Frost/New Hampshire.pdf
# Texts/Robert Frost/In The Clearing.pdf
Texts/Helen Keller/The Story of My Life.pdf
Texts/Saki/The Short Stories of Saki.pdf
# Texts/Jane Austen/Sense and Sensibility.pdf
Texts/Jane Austen/Pride and Prejudice.pdf
# Texts/Richard Connell/The Stolen Crime.pdf
Texts/Richard Connell/The Most Dangerous Game.txt
# Texts/Mary Wollstonecraft Shelley/Mathilda.epub
Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf
# Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf
Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm

Vous pouvez ensuite filtrer les lignes commentées avec grepet diriger le résultat vers xargspour les transmettre à mv:

grep -Pv '^\s*#' manifest | xargs -d '\n' mv -t 'Glorious Destination Folder'

Comme ci-dessus, remplacez Glorious Destination Folderpar le nom de la destination réelle. C'est ça; vos fichiers sont déplacés. Vous pouvez bien sûr écrire echoavant mvpour voir les commandes qui seront exécutées en premier, si vous le souhaitez.

Le fonctionnement de cette commande est le suivant:

  1. La grepcommande génère des lignes à partir de manifestce don't ( -v) start ( ^) avec des *espaces ( \s) optionnels ( ) suivis d'un #caractère littéral . Le -Pdrapeau sélectionne PCRE comme dialecte des expressions régulières (ce qui permet \sque je considère plus lisible que le traditionnel [[:space:]]).
  2. La xargscommande divise son entrée (qui est la sortie de grep) en champs terminés par une nouvelle ligne ( -d '\n'), puis colle chaque champ (sans la nouvelle ligne de fin) en tant qu'argument distinct à la fin de la commande mv -t 'Glorious Destination Folder', qu'elle exécute.
Eliah Kagan
la source
1
-okÀ
mon humble avis
7

Voici un petit script ( mv-confirm.sh):

#!/bin/bash

# Just make sure there are at least one source and one destination
if [ "$#" -lt 2 ]; then
    echo "Illegal number of parameters"
fi

DESTINATION=${*:$#}             # last argument
SOURCES=( ${@:1:$#-1} )         # all but last arguments

for i in "${SOURCES[@]}"
do
    read -p "move '$i' to '$DESTINATION' ? [y/n] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
        echo mv "$i" "$DESTINATION"
    fi
done

Exemple d'utilisation:

./mv-confirm.sh ** somewhere
move 'a' to 'somewhere' ? [y/n] n
move 'b' to 'somewhere' ? [y/n] y
mv b d
...

n'oubliez pas de rendre le script exécutable ( chmod +x mv-confirm.sh).

NB

Comme je ne veux pas jouer avec vos fichiers, j'ai ajouté echoavant la mv commande réelle . N'hésitez pas à le supprimer pour déplacer réellement les fichiers.

pim
la source