ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.3 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://adamheins.com/blog/cut-copy-paste-files-cli |
| Last Crawled | 2026-04-05 10:50:00 (9 days ago) |
| First Indexed | 2021-07-12 01:28:54 (4 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Cut, Copy, and Paste Files from the Command Line |
| Meta Description | Conveniently cut, copy, and paste files between directories without leaving the terminal. |
| Meta Canonical | null |
| Boilerpipe Text | I prefer to work from the command line, often switching between many terminals
via something like tmux. I think it would be convenient to be able to cut,
copy, and paste files between the current working directories (CWDs) in
different terminals without having to write out the relative paths. For
example, if the CWD of my terminal is
/a/b/c/
and I want to copy a file
called
foo.txt
to directory
/d/e/f/
, then I have to write
cp
foo.txt
..
/
..
/
..
/d/e/f
Analogously, to move the file without copying (analogous to the “cut” verb of
GUIs), I’d write
mv
foo.txt
..
/
..
/
..
/d/e/f
Writing out the whole relative path
../../../d/e/f
is pretty annoying (
did I
get the number of
..
right?
), especially if I already have another terminal
open with CWD
/d/e/f/
. I would prefer to be able to somehow cut or copy the
file in one terminal then paste it in another, similar to how GUI file managers
typically work.
A while ago I wrote a
Python
tool
to provide this
functionality by copying files to and from an intermediate directory. However,
I no longer use this tool because there are simpler methods, two of which I’ll
discuss here.
xclip
Probably the simplest method of all is to just use
xclip
, which comes with the commands
xclip-copyfile
xclip-cutfile
xclip-pastefile
which do exactly what we want. For convenience, I’d probably alias these to
something shorter like
alias
xcp
=
xclip-copyfile
alias
xmv
=
xclip-cutfile
alias
pst
=
xclip-pastefile
The names
xcp
and
xmv
are inspired both by
x
in
xclip
as well the
great
renameutils
package, which
provides the quick (
qcp
,
qmv
) and interactive (
icp
,
imv
) variants of
cp
and
mv
. These commands can be quite handy, so I’d recommend checking out
renameutils if you haven’t before.
One thing I don’t like about this solution is that once a file has been cut
using
xclip-cutfile
, it’s stuck in the mysterious xclip clipboard. If I
accidentally copy or cut something else before I paste it, then it’s gone.
Another (smaller) downside is that the file in the clipboard can only be pasted
once, when I might like to copy the same file to multiple destinations.
A simple shell script
In an attempt to remedy the drawbacks of the xclip solution, I wrote a simple
alternative shell script. Instead of the traditional order of cut or copy, then
paste, I actually felt it to be more elegant to “mark” a set of files and then
choose whether they should be copied or moved to the new location. Before I
explain further, here is the script itself (you can also find it
here
):
CLIPBOARD_FILE
=~
/.xcp-clipboard
# mark the file(s) for later use with cp or mv
xmark
(
)
{
realpath
"
$@
"
>
"
$CLIPBOARD_FILE
"
}
# copy the marked files
xcp
(
)
{
local
files
while
read
line
;
do
files
+=
(
"
$line
"
)
done
<
"
$CLIPBOARD_FILE
"
cp
$files
$@
}
# move the marked files
xmv
(
)
{
local
files
while
read
line
;
do
files
+=
(
"
$line
"
)
done
<
"
$CLIPBOARD_FILE
"
mv
$files
$@
}
To access these commands, you just need to copy the above code to your shell’s
rc file (like the
.bashrc
) or otherwise source it.
Let’s return to our example from the beginning of the post to see how these
commands work. We have two terminal windows: Terminal #1 has CWD
/a/b/c/
and
Terminal #2 has CWD
/d/e/f/
. The goal is to copy
foo.txt
from
/a/b/c/
to
/d/e/f/
without writing tedious relative paths. Making use of the functions
in the above script, in Terminal #1 I can run:
xmark foo.txt
which just “marks” the file by writing its full path
/a/b/c/foo.txt
to the
clipboard file. Now, in Terminal #2, I can just run:
xcp
.
and the file will be copied from its original location to the CWD
/d/e/f/
.
Alternatively I could use
xmv
to move the file (i.e., deleting the original).
Looking at the definitions of the
xcp
and
xmv
functions above, one can see
that they actually just call
cp
and
mv
respectively, except that the paths
listed in the clipboard file are added as the first arguments. Any arguments
supplied to
xmv
or
xcp
get passed along directly to
mv
or
cp
,
respectively, which means we get to leverage all of the power of
mv
and
cp
for free. Want the command to print out what is being done? Pass
-v
(verbose). Want to avoid overwriting an existing file? Use
-n
(no-clobber).
I was surprised by how many options there were when I read the man pages for
for
cp
and
mv
: there is a lot going on there!
And that’s it: as you can see, it is actually quite simple to cut and copy
files from the command line. As usual, I’m interested in hearing about
alternative solutions to the problem, as well as comments on the ones proposed
above. The best way to reach me is by
email
. |
| Markdown | # [Adam Heins](https://adamheins.com/)
[Blog](https://adamheins.com/blog)[Projects](https://adamheins.com/projects)[CV](https://static.adamheins.com/cv.pdf)
July 11, 2021
# Cut, Copy, and Paste Files from the Command Line
I prefer to work from the command line, often switching between many terminals via something like tmux. I think it would be convenient to be able to cut, copy, and paste files between the current working directories (CWDs) in different terminals without having to write out the relative paths. For example, if the CWD of my terminal is `/a/b/c/` and I want to copy a file called `foo.txt` to directory `/d/e/f/`, then I have to write
```
cp foo.txt ../../../d/e/f
```
Analogously, to move the file without copying (analogous to the “cut” verb of GUIs), I’d write
```
mv foo.txt ../../../d/e/f
```
Writing out the whole relative path `../../../d/e/f` is pretty annoying (*did I get the number of `..` right?*), especially if I already have another terminal open with CWD `/d/e/f/`. I would prefer to be able to somehow cut or copy the file in one terminal then paste it in another, similar to how GUI file managers typically work.
A while ago I wrote a [Python tool](https://github.com/adamheins/xcp/tree/old-python-version) to provide this functionality by copying files to and from an intermediate directory. However, I no longer use this tool because there are simpler methods, two of which I’ll discuss here.
## xclip
Probably the simplest method of all is to just use [xclip](https://linux.die.net/man/1/xclip), which comes with the commands
```
xclip-copyfile
xclip-cutfile
xclip-pastefile
```
which do exactly what we want. For convenience, I’d probably alias these to something shorter like
```
alias xcp=xclip-copyfile
alias xmv=xclip-cutfile
alias pst=xclip-pastefile
```
The names `xcp` and `xmv` are inspired both by `x` in `xclip` as well the great [renameutils](https://www.nongnu.org/renameutils/) package, which provides the quick (`qcp`, `qmv`) and interactive (`icp`, `imv`) variants of `cp` and `mv`. These commands can be quite handy, so I’d recommend checking out renameutils if you haven’t before.
One thing I don’t like about this solution is that once a file has been cut using `xclip-cutfile`, it’s stuck in the mysterious xclip clipboard. If I accidentally copy or cut something else before I paste it, then it’s gone. Another (smaller) downside is that the file in the clipboard can only be pasted once, when I might like to copy the same file to multiple destinations.
## A simple shell script
In an attempt to remedy the drawbacks of the xclip solution, I wrote a simple alternative shell script. Instead of the traditional order of cut or copy, then paste, I actually felt it to be more elegant to “mark” a set of files and then choose whether they should be copied or moved to the new location. Before I explain further, here is the script itself (you can also find it [here](https://github.com/adamheins/xcp/blob/master/xcp.sh)):
```
CLIPBOARD_FILE=~/.xcp-clipboard
# mark the file(s) for later use with cp or mv
xmark() {
realpath "$@" > "$CLIPBOARD_FILE"
}
# copy the marked files
xcp() {
local files
while read line; do
files+=("$line")
done < "$CLIPBOARD_FILE"
cp $files $@
}
# move the marked files
xmv() {
local files
while read line; do
files+=("$line")
done < "$CLIPBOARD_FILE"
mv $files $@
}
```
To access these commands, you just need to copy the above code to your shell’s rc file (like the `.bashrc`) or otherwise source it.
Let’s return to our example from the beginning of the post to see how these commands work. We have two terminal windows: Terminal \#1 has CWD `/a/b/c/` and Terminal \#2 has CWD `/d/e/f/`. The goal is to copy `foo.txt` from `/a/b/c/` to `/d/e/f/` without writing tedious relative paths. Making use of the functions in the above script, in Terminal \#1 I can run:
```
xmark foo.txt
```
which just “marks” the file by writing its full path `/a/b/c/foo.txt` to the clipboard file. Now, in Terminal \#2, I can just run:
```
xcp .
```
and the file will be copied from its original location to the CWD `/d/e/f/`. Alternatively I could use `xmv` to move the file (i.e., deleting the original).
Looking at the definitions of the `xcp` and `xmv` functions above, one can see that they actually just call `cp` and `mv` respectively, except that the paths listed in the clipboard file are added as the first arguments. Any arguments supplied to `xmv` or `xcp` get passed along directly to `mv` or `cp`, respectively, which means we get to leverage all of the power of `mv` and `cp` for free. Want the command to print out what is being done? Pass `-v` (verbose). Want to avoid overwriting an existing file? Use `-n` (no-clobber). I was surprised by how many options there were when I read the man pages for for `cp` and `mv`: there is a lot going on there\!
And that’s it: as you can see, it is actually quite simple to cut and copy files from the command line. As usual, I’m interested in hearing about alternative solutions to the problem, as well as comments on the ones proposed above. The best way to reach me is by [email](mailto:mail@adamheins.com).
[Email](mailto:mail@adamheins.com)\ \|\ [GitHub](https://github.com/adamheins)\ \|\ [LinkedIn](https://linkedin.com/in/adamwheins)\ \|\ [RSS](https://adamheins.com/rss.xml)\ \|\ [Scholar](https://scholar.google.com/citations?hl=en&user=4G2IkRUAAAAJ)
Adam Heins \© 2026 |
| Readable Markdown | I prefer to work from the command line, often switching between many terminals via something like tmux. I think it would be convenient to be able to cut, copy, and paste files between the current working directories (CWDs) in different terminals without having to write out the relative paths. For example, if the CWD of my terminal is `/a/b/c/` and I want to copy a file called `foo.txt` to directory `/d/e/f/`, then I have to write
```
cp foo.txt ../../../d/e/f
```
Analogously, to move the file without copying (analogous to the “cut” verb of GUIs), I’d write
```
mv foo.txt ../../../d/e/f
```
Writing out the whole relative path `../../../d/e/f` is pretty annoying (*did I get the number of `..` right?*), especially if I already have another terminal open with CWD `/d/e/f/`. I would prefer to be able to somehow cut or copy the file in one terminal then paste it in another, similar to how GUI file managers typically work.
A while ago I wrote a [Python tool](https://github.com/adamheins/xcp/tree/old-python-version) to provide this functionality by copying files to and from an intermediate directory. However, I no longer use this tool because there are simpler methods, two of which I’ll discuss here.
## xclip
Probably the simplest method of all is to just use [xclip](https://linux.die.net/man/1/xclip), which comes with the commands
```
xclip-copyfile
xclip-cutfile
xclip-pastefile
```
which do exactly what we want. For convenience, I’d probably alias these to something shorter like
```
alias xcp=xclip-copyfile
alias xmv=xclip-cutfile
alias pst=xclip-pastefile
```
The names `xcp` and `xmv` are inspired both by `x` in `xclip` as well the great [renameutils](https://www.nongnu.org/renameutils/) package, which provides the quick (`qcp`, `qmv`) and interactive (`icp`, `imv`) variants of `cp` and `mv`. These commands can be quite handy, so I’d recommend checking out renameutils if you haven’t before.
One thing I don’t like about this solution is that once a file has been cut using `xclip-cutfile`, it’s stuck in the mysterious xclip clipboard. If I accidentally copy or cut something else before I paste it, then it’s gone. Another (smaller) downside is that the file in the clipboard can only be pasted once, when I might like to copy the same file to multiple destinations.
## A simple shell script
In an attempt to remedy the drawbacks of the xclip solution, I wrote a simple alternative shell script. Instead of the traditional order of cut or copy, then paste, I actually felt it to be more elegant to “mark” a set of files and then choose whether they should be copied or moved to the new location. Before I explain further, here is the script itself (you can also find it [here](https://github.com/adamheins/xcp/blob/master/xcp.sh)):
```
CLIPBOARD_FILE=~/.xcp-clipboard
# mark the file(s) for later use with cp or mv
xmark() {
realpath "$@" > "$CLIPBOARD_FILE"
}
# copy the marked files
xcp() {
local files
while read line; do
files+=("$line")
done < "$CLIPBOARD_FILE"
cp $files $@
}
# move the marked files
xmv() {
local files
while read line; do
files+=("$line")
done < "$CLIPBOARD_FILE"
mv $files $@
}
```
To access these commands, you just need to copy the above code to your shell’s rc file (like the `.bashrc`) or otherwise source it.
Let’s return to our example from the beginning of the post to see how these commands work. We have two terminal windows: Terminal \#1 has CWD `/a/b/c/` and Terminal \#2 has CWD `/d/e/f/`. The goal is to copy `foo.txt` from `/a/b/c/` to `/d/e/f/` without writing tedious relative paths. Making use of the functions in the above script, in Terminal \#1 I can run:
```
xmark foo.txt
```
which just “marks” the file by writing its full path `/a/b/c/foo.txt` to the clipboard file. Now, in Terminal \#2, I can just run:
```
xcp .
```
and the file will be copied from its original location to the CWD `/d/e/f/`. Alternatively I could use `xmv` to move the file (i.e., deleting the original).
Looking at the definitions of the `xcp` and `xmv` functions above, one can see that they actually just call `cp` and `mv` respectively, except that the paths listed in the clipboard file are added as the first arguments. Any arguments supplied to `xmv` or `xcp` get passed along directly to `mv` or `cp`, respectively, which means we get to leverage all of the power of `mv` and `cp` for free. Want the command to print out what is being done? Pass `-v` (verbose). Want to avoid overwriting an existing file? Use `-n` (no-clobber). I was surprised by how many options there were when I read the man pages for for `cp` and `mv`: there is a lot going on there\!
And that’s it: as you can see, it is actually quite simple to cut and copy files from the command line. As usual, I’m interested in hearing about alternative solutions to the problem, as well as comments on the ones proposed above. The best way to reach me is by [email](mailto:mail@adamheins.com). |
| Shard | 62 (laksa) |
| Root Hash | 2016632194425670462 |
| Unparsed URL | com,adamheins!/blog/cut-copy-paste-files-cli s443 |