4

Every once in a while, I find the need to do:

cp /really/long/path/to/file.txt /totally/different/long/path/to/copy.txt

Since I use autojump, getting to the directories is very fast and easy. However, I'm at a loss when it comes to copying from one directory to the other without having to type out at least one of the full paths.

In a GUI filesystem navigator, this is easy: navigate to the first directory; Copy the original file; navigate to the second directory; and Paste. But with cp, it seems like I can't do the copy in two steps.

I'm looking to do something like the following:

(use autojump to navigate to the first directory)
$ copy file.txt
(use autojump to navigate to the second directory)
$ paste copy.txt

Instead of the longer-to-type:

(use autojump to navigate to the first directory)
$ cp file.txt /totally/different/long/path/to/copy.txt

Is there a tool that provides the functionality I'm looking for? I'm using Zsh on OS X El Capitan.

Resigned June 2023
  • 713
  • 1
  • 8
  • 21

2 Answers2

5

The below works in bash. I haven't tried it in zsh.

Try:

echo ~-   # Just to make sure you know what the "last directory" is

Then:

cp file.txt ~-/copy.txt

Also see:

Wildcard
  • 35,316
  • 26
  • 130
  • 258
  • 1
    This looks perfect! I can use `dirs -v` to check the stack, and then `~#` to reference the other path (where `#` is the integer identifying the directory on the stack). Also, I can confirm this works fine in `zsh`. – Resigned June 2023 Aug 05 '16 at 23:06
1

Here is an alternative solution, inspired by the comment by @Stephen Harris:

# You can "copy" any number of files, then "paste", "move" or
# "pasteln" them to pass them as arguments to cp, mv, or ln
# respectively. Just like a graphical filesystem manager. Each of the
# latter three functions defaults to the current directory as the
# destination.
function copy() {
    emulate -LR zsh
    radian_clipboard=()
    for target; do
        radian_clipboard+=(${target:a})
    done
}
function paste() {
    emulate -LR zsh
    cp -R $radian_clipboard ${1:-.}
}
function move() {
    emulate -LR zsh
    mv $radian_clipboard ${1:-.}
}
function pasteln() {
    emulate -LR zsh
    ln -s $radian_clipboard ${1:-.}
}

Example usage:

(autojump to first directory)
$ copy file.txt
(autojump to second directory)
$ paste copy.txt

As you can see, these aliases are very thin wrappers around the cp, mv, and ln -s commands, so you can also pass a directory as the second argument, or copy multiple files or directories at once, or omit the second argument to act on the current directory.

Resigned June 2023
  • 713
  • 1
  • 8
  • 21
  • 1
    `paste` is already [a POSIX-specified tool](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/paste.html), but I like this idea. You could improve it further by checking the number of arguments to `copy` and the number of arguments to `paste` and defaulting to `./` if no argument given to `paste`. You could even use `bash` arrays to allow multiple files to be copied, at which point `paste` would not accept any arguments but would just run `cp -i "${copy_paths[@]}" .` (or do nothing if `copy_paths` is empty). – Wildcard Aug 06 '16 at 01:08