2014-09-24 4 views
1

Я пытаюсь создать оболочку для одного liner, чтобы найти все jpegs в каталоге рекурсивно. Затем я хочу скопировать их во внешний каталог, переименовав их в соответствии с их датой и временем, а затем добавьте случайное целое число, чтобы избежать перезаписи изображений, имеющих одну и ту же метку времени.Найти рекурсивные/xargs/cp/awk/sed/одиночные кавычки в одиночной кавычки вместе в одном слоте

Первая попытка:

find /storage/sdcard0/tencent/MicroMsg/ -type f -iname '*.jpg' -print0 | xargs -0 sh -c 'for filename; do echo "$filename" && cp "$filename" $(echo /storage/primary/legacy/image3/$(stat $filename |awk '/Mod/ {print $2"_"$3}'|sed s/:/-/g)_$RANDOM.jpg);done' fnord

Среди прочего, выше не работает, потому что есть одиночные кавычки о AWK внутри ш -с одинарных кавычек.

Вторая попытка должна сделать то же самое без ш -с, но дает мне эту ошибку на стат:

stat: can't stat '': No such file or directory 
/system/bin/sh: file: not found 

Вторая попытка:

find /storage/sdcard0/tencent/MicroMsg/ -type f -iname '*.jpg' -print0 | xargs -0 file cp "$file" $(echo /storage/primary/legacy/image3/$(stat "$file" | awk '/Mod/ {print $2"_"$3}'|sed s/:/-/g)_$RANDOM.jpg)

Я думаю, что проблема с Вторая попытка может быть слишком много подоболочек?

Может ли кто-нибудь помочь мне узнать, где я здесь ошибся?

На другом примечании: если кто знает, как сохранить актуальный измененный штамп даты/времени при копировании файла, мне бы понравился этот бросок здесь.

Спасибо Спасибо

+2

Что увлечение с однострочником? Он просто делает для нечитаемого кода. Если вы имеете в виду один конвейер, это совсем другое; он не должен находиться на одной линии. –

+0

Вы можете написать сценарий, а не искать «неопрятный» одиночный лайнер, чтобы сделать его нечитаемым. – iqstatic

+0

Нужно ли использовать все эти команды? Может ли он просто использовать Perl или Python? Не могли бы вы написать сценарий оболочки, который обрабатывает список файлов ('для файла в $ @", do ... code here для одного файла ...; done'), а затем использовать 'find ... -exec script.sh {} +'. Это позволяет избежать необходимости «xargs». Вероятно, вы можете использовать 'stat -c '% y'' (или'% Y'), чтобы получить время изменения файла, сохраняя пост-обработку вывода 'stat'. –

ответ

0

Были это моя проблема, я бы создать сценарий - назовем его filecopy.sh - как это:

TARGET="/storage/primary/legacy/image3" 
for file in "[email protected]" 
do 
    basetime=$(date +'%Y-%m-%d.%H-%M-%S' -d @$(stat -c '%Y' "$file")) 
    cp "$file" "$TARGET/$basetime.$RANDOM.jpg" 
done 

basetime линия проходит stat, чтобы получить время изменения файл за считанные секунды с The Epoch, затем использует это с date, чтобы отформатировать время как измененный формат ISO 8601 (используя - вместо : и . вместо T). Затем он используется для создания имени целевого файла вместе с полуслучайным числом.

Затем команда find становится просто:

SOURCE="/storage/sdcard0/tencent/MicroMsg" 
find "$SOURCE" -type f -iname '*.jpg' -exec /path/to/filecopy.sh {} + 

Лично я бы не беспокоить, чтобы попытаться заставить его работать без отдельного скрипта. Это может быть сделано, но это не было бы тривиально:

SOURCE="/storage/sdcard0/tencent/MicroMsg" 
find "$SOURCE" -type f -iname '*.jpg' -exec bash -c \ 
    'TARGET="/storage/primary/legacy/image3" 
    for file in "[email protected]" 
    do 
     basetime=$(date +%Y-%m-%d.%H-%M-%S -d @$(stat -c %Y "$file")) 
     cp "$file" "$TARGET/$basetime.$RANDOM.jpg" 
    done' command {} + 

Я взял некоторые вольности в том, что путем удаления одинарные кавычки, которые я использовал в основном сценарии оболочки. Они были необязательными, но я бы использовал их автоматически при обычных обстоятельствах.

0

Если у вас есть GNU Parallel> Версия 20140722 вы можете запустить:

find . | parallel 'cp {} ../destdir/{= $a = int(10000*rand); $_ = `date -r "$_" +%FT%T"$a"`; chomp; =}' 

Он будет работать на имена файлов, содержащих 'и пространство, но не на имена файлов, содержащих»

Все новые компьютеры имеют. несколько ядер, но большинство программ носят последовательный характер и поэтому не будут использовать несколько ядер.Тем не менее, многие задачи чрезвычайно parallelizeable:

  • Выполнить ту же программу на многих файлах
  • Выполнить ту же самую программу для каждой строки в файле
  • Run та же программа для каждого блока в файле

GNU Parallel - это общий параллелизатор и позволяет легко запускать задания параллельно на одном компьютере или на нескольких компьютерах, к которым у вас есть доступ ssh.

Если у вас есть 32 различных заданий, которые вы хотите работать на 4-х процессоров, прямо вперед способ распараллеливания является выполнение 8 заданий на каждом CPU:

Simple scheduling

GNU Parallel вместо порождает новый процесс, когда один заканчивается - поддержание процессоров активным и тем самым экономя время:

GNU Parallel scheduling

Установка

Личная установка не требует доступа root. Это может быть сделано в течение 10 секунд, делая это:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

Для других вариантов установки см http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Подробнее

Другие примеры: http://www.gnu.org/software/parallel/man.html

смотреть интро видео: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Прогулка по t он учебник: http://www.gnu.org/software/parallel/parallel_tutorial.html

Зарегистрируйтесь на список адресов электронной почты, чтобы получить поддержку: https://lists.gnu.org/mailman/listinfo/parallel