В bash поиск, сортировка и копирование

#bash #sorting #terminal #copy #find

#bash #сортировка #терминал #Копировать #Найти

Вопрос:

Я пытаюсь выполнить поиск по папке со многими папками и файлами. Я хотел бы найти последние 20 quicktimes и скопировать в определенный каталог «New_Directory».

Пока я понял это:

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

Это находит мои файлы и печатает их с указанием размера / даты / имени (начиная с ./)

Но если я изменю команду на эту (добавив cp в конце):

 find .  -type f -name '*.mov' -print0 | xargs -0 ls -dtl | head -20 | xargs -I{} cp {} /Volume/New_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
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)
 

Я использую терминал в Mac OS.

Пожалуйста, предложите, как это можно исправить, или, пожалуйста, предложите лучший подход. Спасибо.

Комментарии:

1. Попробуйте изменить cp {} на cp «{}»

2. @RamanSailopal не помогло, та же ошибка … 🙁

3. Если вы передадите имя ls -dtl файла, вы получите больше информации, например, размер / дату и т. Д., Как вы описали. Передача этих строк в cp не сработает. Почему xargs -0 ls -dtl часть?

4. @0stone0 спасибо за комментарий, мне нужно отсортировать по дате, поиск новейших 20, может быть, я могу просто сохранить ls -dt, кажется, работает..

5. в bash find встроены все эти требования.

Ответ №1:

Попробуйте разобрать свой конвейер, чтобы увидеть, что происходит.

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

предоставляет вам список из 20 новейших mov файлов. Потерянный выглядит как:

 -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
 

Итак, вы xargs|cp получите это в качестве входных данных.

Это будет

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

Если мы посмотрим на ваше сообщение об ошибке,

 cp: illegal option -- w
 

cp -r нормально, cp -rw выдаст это сообщение. Так что это согласуется с тем, что я сказал.

Итак, вопрос в том, почему -l в копии. Если вы удалите длинный формат, вы получите именно то, что вам нужно.

В качестве примечания, почему ls -d , если вы find гарантируете -type f ?

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

следует делать то, что вы хотите, но помните, что вы анализируете выходные ls данные, что считается не очень хорошей идеей.

Лично я бы

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

Комментарии:

1. я действительно удалил «-l», как было предложено, работает как шарм.

2. «.. анализ выходных данных ls, что считается не очень хорошей идеей». — почему бы и нет? что было бы лучшим решением? Спасибо!!!

3. Когда я ищу в своем Google bubble ‘parse ls output’, первый удар, который я получаю, это unix.stackexchange.com/questions/128985 /… . Как TL; DR: непереносимость через unices, неожиданная обработка специальных символов и тому подобное.

Ответ №2:

вы используете приведенный ниже скрипт.

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