With recent[1] versions of GNU findutils
and coreutils
:
find /home/jeremy/source -print0 |
tail -z -n 1000 |
xargs -0 -r mv -t /home/jeremy/dest/
The -print0
, -z
, and -0
options tell all three tools to use a NUL character as the filename/record separator. This makes it safe to use this pipeline with filenames containing ANY character.
If your version of tail
(or head
) doesn't support the -z
option, you can use newline as the filename delimiter (which will be safe for ANY filename except those containing newlines):
find /home/jeremy/source |
tail -n 1000 |
xargs -r -d '\n' mv -t /home/jeremy/dest/
BTW, xargs
isn't tricky at all. It's a fairly simple command that takes data from stdin and uses it to run programs (with the data from stdin used as arguments on that program's command-line). It's a useful tool that's well worth the small amount of time it takes to learn.
More importantly, unlike $(ls ...)
and similar, using xargs
avoids most (all if you use NUL as separator) problems with spaces, shell globbing characters (wildcards etc), and other annoying characters (which are perfectly legitimate characters in filenames, so a well-written script will take care not to be broken by them).
[1] I don't exactly know when head
and tail
got -z
options, but over the last few years, many of the GNU tools (including sort
) have gained the ability to use NUL as the input record separator. Before that, it was only a handful of tools like find
and xargs
.
This is extremely useful, as you can now use these -z
or -Z
or -0
etc options to build long, complicated pipelines without ever having to lose that useful NUL-separation.
ls
– glenn jackman Apr 29 '16 at 13:03