ускорить скрипт bash, запустив несколько экземпляров в цикле for

У меня есть этот скрипт:

 for i in `find ! -newermt "2016-02-13" -name "*svgz"`; do
  inkscape --verb FitCanvasToDrawing --verb FileSave --verb FileClose ${i} --verb FileQuit
done

, который ждет, когда inkscape завершит свое задание, а затем перезапустит его со следующим файлом. Я бы хотел, чтобы четыре экземпляра inkscape выполнялись параллельно, чтобы ускорить процесс (у меня есть ~ 5000 файлов для обработки). Это возможно, и если да, то как? Спасибо заранее!

1
задан 29 February 2016 в 15:38

2 ответа

Вы можете использовать GNU-параллель, как объясняется здесь для очень похожего вопроса, также связанного с inkscape: https://stackoverflow.com/questions/26572397/how-to-process-20k-svg-files-with-inkscape-cli -mode-align-and-merge-objects

Еще один простой трюк, который я использовал в последнее время, выглядит следующим образом:

Создает shellscript «process.sh», обрабатывая один файл, переданный как аргумент к нему. Сохраните результат команды find в текстовом файле. Разделите файл, используя команду «split», на столько заданий, сколько вы хотите запускать параллельно. Запустите несколько экземпляров process.sh, передавая ему аргументы через сгенерированные файлы split и xargs.
1
ответ дан 23 May 2018 в 13:11

Вот как я подхожу к этому. Так как у меня нет одинаковых файлов, приведенный ниже пример кода предназначен для открытия 4 текстовых файлов с помощью gedit.

Как это работает? Ну, сначала мы найдем файлы в жестко закодированном месте, где файлы могут быть сохранены (переменная FILEPATH). Затем мы переходим к структуре while read. Обратите внимание на использование -print0 и IFS= read -d''. Это очень часто встречается при программировании bash для устранения проблемных имен файлов, содержащих пробелы, непечатаемые символы и т. Д.

Каждый gedit file & вызывает gedit, который отделяется от скрипта с помощью &. Это делает цикл while без остановки.

Что делает останов цикла, это переменная COUNT. Как только мы посчитаем от 0 до некоторого числа, делящегося на 4, переменная MOD, которая вычисляется из оператора модуля, станет 0. Теперь оболочка будет ожидать всплывающее окно (которое является zenity), чтобы подтвердить, что нерест еще 4 окна , Таким образом, мы подсчитываем 4 раза, сбрасываем переменную, продолжаем.

Единственный минус здесь заключается в том, что find не сортирует файлы, поэтому они не обязательно будут в именованном порядке. Если порядок имеет значение, код потребует дополнительных инструкций. В противном случае это достаточно.

#!/bin/bash

FILEPATH="/home/xieerqi/MYTEXTFILES"
COUNT=0

find $FILEPATH -type f -name "*.txt" -print0 | \
while IFS= read -d ''  FILE;
do
    gedit $FILE & 
    COUNT=$(( $COUNT+1 ))
    MOD=$(( $COUNT % 4 ))

    if [ $MOD -eq 0   ]
    then 
        zenity --question --text "Open 4 more files?"  || exit
    fi
done
0
ответ дан 23 May 2018 в 13:11
  • 1
    Спасибо за хороший сценарий. Это не помогает в моем случае, хотя, поскольку у меня есть около 2000 файлов для открытия и редактирования (которые все равно заставят примерно 500 раз отвечать на всплывающее окно zenity ...) ;-) Есть ли «wait " команду, которую я мог бы использовать, чтобы ждать 10 секунд до следующего цикла? Может быть, этого хватит ... – HinzundKunz 1 March 2016 в 13:38
  • 2
    В этом случае sleep 10 - команда, которая вам нужна – Sergiy Kolodyazhnyy 1 March 2016 в 17:25

Другие вопросы по тегам:

Похожие вопросы: