Presse-papiers pour copier et coller des fichiers en ligne de commande?

25

Dans Bash, supposons que je visite un répertoire, puis un autre répertoire. Je voudrais copier un fichier du premier répertoire vers le deuxième répertoire, mais sans en spécifier les longs chemins d'accès. C'est possible?

Ma solution temporaire consiste à utiliser /tmpcomme un emplacement temporaire pour stocker une copie du fichier. cp myfile /tmpquand je suis dans le premier répertoire, puis cp /tmp/myfile .quand je suis dans le deuxième répertoire. Mais je peux vérifier si le fichier remplacera quoi que ce soit /tmp.

Existe-t-il quelque chose de similaire à un presse-papiers pour copier et coller un fichier?

Tim
la source
1
Vous devez taper la cdcommande, vous pouvez donc simplement cd -revenir au répertoire précédent, flèche vers le haut pour rappeler la cdcommande et modifier la ligne pour être à la cpplace de cd. (ctrl-a (début de ligne), alt-d (mot-clé) cp -a,, ctrl-e (fin de ligne)).
Peter Cordes
Avec Emacs et M-x termvous pouvez utiliser le presse-papiers d'Emacs.
Pål GD
1
Vous pouvez utiliser Midnight Commander et oublier de sauter à travers les cerceaux.
Deer Hunter
@ PålGD Les gens disent qu'Emacs est un système d'exploitation ... La plupart ont des presse-papiers;)
Volker Siegel
@JeffSchaller thanks ................................
Tim

Réponses:

59

En utilisant Bash, je visiterais simplement les répertoires:

$ cd /path/to/source/directory
$ cd /path/to/destination/directory

Ensuite, j'utiliserais le raccourci ~-, qui pointe vers le répertoire précédent:

$ cp -v ~-/file1.txt .
$ cp -v ~-/file2.txt .
$ cp -v ~-/file3.txt .

Si l'on veut visiter les répertoires dans l'ordre inverse, alors:

$ cp -v fileA.txt ~-
$ cp -v fileB.txt ~-
$ cp -v fileC.txt ~-
Anderson Medeiros Gomes
la source
25
+1 J'utilise des shells Unix / Linux depuis plus de 20 ans maintenant, et je ne connaissais pas ce raccourci.
Dubu
4
Huh, c'est un raccourci pratique pour "$OLDPWD". cpMais pourquoi trois commandes distinctes ? cp -a ~-/file[1-3].txt .
Peter Cordes
4
En fait, les trois cpsont des exemples. Dans le monde réel, les caractères génériques peuvent également être utilisés pour simplifier la tâche de copie.
Anderson Medeiros Gomes
2
J'allais mentionner quelque chose pushdet analyser dirs... mais c'est beaucoup, beaucoup mieux. Je vous suggère d'ajouter le fait qu'il "$OLDPWD"est exactement équivalent ~-et plus portable (utile pour ceux qui n'utilisent pas bash.)
Wildcard
1
~+est également un raccourci pour"$PWD"
Paul Evans
11

Si je voyais cette situation comme unique, je pourrais:

a=`pwd`
cd /somewhere/else
cp "$a/myfile" .

S'il y avait des répertoires dans lesquels je me trouvais à copier des fichiers de manière semi-régulière, je définirais probablement des variables mnémoniques pour eux dans mon .profile.

Modifié pour ajouter:

Après avoir dormi dessus, je me suis demandé dans quelle mesure je pouvais me rapprocher d'autres comportements GUI / OS où vous sélectionnez un certain nombre de fichiers, les "coupez" ou les "copiez", puis les "collez" ailleurs. Le meilleur mécanisme de sélection que j'ai pu trouver était votre cerveau / vos préférences ainsi que la fonction de globbing de la coquille. Je ne suis pas très créatif avec le nommage, mais c'est l'idée de base (dans la syntaxe Bash):

function copyfiles {
  _copypastefiles=("$@")
  _copypastesrc="$PWD"
  _copypastemode=copy
}

function cutfiles {
  _copypastefiles=("$@")
  _copypastesrc="$PWD"
  _copypastemode=cut
}

function pastefiles {
  for f in "${_copypastefiles[@]}"
  do
    cp "${_copypastesrc}/$f" .
    if [[ ${_copypastemode} = "cut" ]]
    then
      rm "${_copypastesrc}/$f"
    fi
  done
}

Pour l'utiliser, placez le code dans ~ / .bash_profile, puis cddans le répertoire source et exécutez soit copyfiles glob*hereou cutfiles glob*here. Tout ce qui se passe, c'est que votre shell développe les globes et place ces noms de fichiers dans un tableau. Vous accédez ensuite cdau répertoire de destination et exécutez pastefiles, qui exécute une cpcommande pour chaque fichier source. Si vous aviez auparavant "coupé" les fichiers, alors pastefiles supprime également le fichier source (ou essaie de le faire). Cela ne fait aucune vérification d'erreur (des fichiers existants, avant de potentiellement les encombrer avec le cp; ou que vous avez les autorisations pour supprimer les fichiers pendant une "coupe", ou que vous pouvez accéder à nouveau au répertoire source après avoir quitté de celui-ci).

Jeff Schaller
la source
4
Pour votre one-off, $OLDPWDexiste déjà, qui peut être raccourci ~-en bash et zsh.
Gilles 'SO- arrête d'être méchant'
5

Je pense que ~-c'est la bonne réponse, mais notez que bash a un éditeur de ligne intégré qui peut copier / coller du texte.

Si vous êtes en mode emacs, vous pouvez rappeler votre cdcommande à partir de l'historique et l'utiliser Control-upour tuer la ligne dans le "presse-papier" bash appelé le kill-ring (il existe également d'autres moyens). Vous pouvez ensuite extraire cette chaîne dans une nouvelle commande à tout moment avec Control-y. Évidemment, dans votre exemple, cela dépend de votre utilisation d'un nom de répertoire absolu dans votre cdcommande.

Vous pouvez également utiliser le raccourci clavier par défaut intéressant de Meta-.. Cela copie le dernier mot de la commande précédente dans votre ligne actuelle. S'il est répété, il revient à chaque fois une commande dans l'historique. Donc , si vous faites cd /x, puis cd /ysuivi , cdMeta-.Meta-.vous aurez /xdans votre entrée.

meuh
la source
5

Développant la réponse d'Anderson M. Gomes , Bash vous permet de faire référence à n'importe quel répertoire antérieur de votre pile de répertoires en tapant ~N(ou ~+N) où se Ntrouve la position sur la pile de répertoires . Par exemple:

# go some places
$ cd /path/to/source/directory
$ pushd /path/to/destination/directory
$ pushd $HOME
$ pushd /tmp

# show the current dir stack
$ dirs -v
0 /tmp
1 ~
2 /path/to/destination/directory
3 /path/to/source/directory

Vous pouvez maintenant copier un fichier entre deux répertoires antérieurs, aucun d'entre eux le répertoire actuel, avec:

cp -v ~3/file1.txt ~2

Pour résoudre le problème de l'affiche originale, vous feriez:

$ cd /path/to/source/directory
$ pushd /path/to/destination/directory

# show the current dir stack
$ dirs -v
0 /path/to/destination/directory
1 /path/to/source/directory

# copy
cp -v ~1/file[123].txt .

Avec un grand ensemble de fichiers, vous pouvez lister leurs noms dans un fichier manifeste puis faire la copie à partir du répertoire source:

$ cd /path/to/destination/directory
$ pushd /path/to/source/directory

# copy
cp -v $(cat files_to_copy.list) ~1

Voir aussi: cette section de la page de manuel de Bash


De même, dans Tcsh, vous pouvez utiliser la =2notation (plutôt que ~2) pour faire référence au deuxième répertoire de votre pile de répertoires.

Voir aussi: cette section de la page de manuel Tcsh

jskroch
la source
4

lorsque vous êtes dans le premier répertoire, disons la source ou srcen bref, exécutez

src=${PWD}

puis cddans le deuxième répertoire et exécutez:

cp -i ${src}/filename .

l' -ioption vous demandera si vous souhaitez remplacer, s'il y a un fichier en double

MelBurslan
la source
Merci. C'est encore mieux sans spécifier le nom du fichier.
Tim
4

Une variation de la réponse d'anderson-m-gomes. En utilisant Bash, je visiterais simplement les répertoires:

$ cd /path/to/source/directory
$ cd /path/to/destination/directory

Ensuite, j'utiliserais la variable $ OLDPWD, qui pointe vers le répertoire précédent:

$ cp -v $OLDPWD/file1.txt .

Si l'on veut visiter les répertoires dans l'ordre inverse, alors:

$ cp -v fileA.txt $OLDPWD/
Scott Carlson
la source
3
+1, mais vous avez oublié de "citer" vos extensions de variable. Si $OLDPWDcontient des espaces, cela se casse. Aussi, j'utilise toujours cp -a. De plus, il est regrettable que la complétion de tabulation soit interrompue sur les extensions variables. Cependant, vous pouvez utiliser ctrl-alt-e pour développer la ligne de commande en cours après avoir tapé la partie $ OLDPWD.
Peter Cordes
1
~-est un raccourci pour$OLDPWD
Gilles 'SO- arrête d'être méchant'
Je viens de signaler une autre variante, car Unix / Linux en regorge. C'est drôle que j'utilise Linux depuis> 20 ans et que je n'avais jamais vu ~ - auparavant. De plus, $ OLDPWD est facile à retenir.
Scott Carlson
3

Si en bash, j'utiliserais pushd et popd . Ces commandes conservent une pile FIFO pratique de répertoires pour une utilisation ultérieure. Vous pouvez consulter la pile à tout moment à l'aide de dirs .

En tant que tel, je ferais:

pushd .
cd /somewhere/else
cp "`popd`/myfile"
Rui F Ribeiro
la source
2

Vous pouvez utiliser xclip:

NAME
       xclip - command line interface to X selections (clipboard)

SYNOPSIS
       xclip [OPTION] [FILE]...

DESCRIPTION
       Reads  from standard in, or from one or more files, and makes the data available as an X selection for pasting
       into X applications. Prints current X selection to standard out.

Exemple:

$ cd /path/to/dir1
$ xclip-copyfile file1 file2
$ cd /path/to/dir2
$ xclip-pastefile
file1 file2

Visitez également xsel .

Pandya
la source
Cela fait une tar | gzipentrée / sortie du presse-papiers X. Un peu maladroit par rapport à cp, et ne se généralise pas à faire des liens symboliques ou des liens durs. ( cp -asou cp -al)
Peter Cordes
1

Vous pouvez consulter le clipboard-filesscript ici: https://github.com/larspontoppidan/clipboard-files

Il fournit des commandes comme ccopy, ccutet cpastequi utilisent le presse-papiers de l'environnement de bureau et permettent un copier / coller intuitif des fichiers:

ccopy myfile
cd <second directory>
cpaste

Lorsque le presse-papiers de l'environnement de bureau est utilisé, le copier / coller interagira avec les fichiers placés dans le presse-papiers dans d'autres programmes tels que les gestionnaires de fichiers et les IDE. Au moins, cela fonctionne sur les ordinateurs de bureau de type Gnome.

Divulgation complète, j'ai écrit le script après avoir renoncé à trouver quelque chose comme ça là-bas ...

Larsp
la source