Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
480 views
in Technique[技术] by (71.8m points)

sorting - In bash, Find, Sort and Copy

I'm trying to run a search on folder with many folders and files. I would like to find latest 20 quicktimes and copy to specific directory "New_Directory".

So far I got this:

find .  -type f -name '*.mov' -print0 | xargs -0 ls -dtl | head -20 | xargs -I{} echo {}

This finds me files and prints them with size/date/name (starting with ./)

But if I change command to this (adding cp at the end):

find .  -type f -name '*.mov' -print0 | xargs -0 ls -dtl | head -20 | xargs -I{} cp {} /Volume/New_Directory/

I get error:

cp: illegal option -- w
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file ... target_directory
cp: illegal option -- w
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file ... target_directory
.... (20 times)

I'm using terminal on mac OS.

Please suggest how this can be fixed or please suggest a better approach. Thank you.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try deconstructing your pipeline to see what is happening.

find .  -type f -name '*.mov' -print0 | xargs -0 ls -dtl | head -20 | 

gives you a list of 20 newest mov files. The lost looks like:

-rw-r--r-- 1 ljm users 12449464 Jan 10 16:24 ./05ED-E769/DCIM/215___01/IMG_5902.mov
-rw-r--r-- 1 ljm users 14153909 Jan 10 16:00 ./05ED-E769/DCIM/215___01/IMG_5901.mov
-rw-r--r-- 1 ljm users 13819624 Jan 10 15:58 ./05ED-E769/DCIM/215___01/IMG_5900.mov

So, your xargs|cp will get this as input.

It will be

cp -rw-r--r-- 1 ljm users 13819624 Jan 10 15:58 ./05ED-E769/DCIM/215___01/IMG_5900.mov /Volume/New_Directory/

If we look at your error message,

cp: illegal option -- w

cp -r is ok, cp -rw will produce this message. So that is consistent with what I said.

So, the question is why the -l in the copy. If you remove the long format, you get exactly what you need.

As a side note why ls -d, if your find ensures -type f?

find .  -type f -name '*.mov' -print0 | xargs -0 ls -t | head -20 | xargs -I{} cp {} /Volume/New_Directory/

should do what you want, but remember that you are parsing the output of ls, which is considered not a good idea.

Personally, I would

find . -type f -printf "%T@ %p
" |
    sort -n |
    cut -d' ' -f 2- |
    tail -n 20 |
    xargs -I{} cp {} /Volume/New_Directory/

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...