В чем разница между find с -exec и xargs?

Простой ответ - да, но он не обеспечивает 100% -ную проверку. Иногда Live CD или USB обеспечивают хорошую производительность, а система, установленная с одного и того же Live CD или USB, будет страдать от неправильно сконфигурированных драйверов с (очень) серьезным снижением производительности.

См. Https://askubuntu.com/questions / 79878 / live-cd-live-usb-much-faster-than-full-install для справки. Кажется, мне не повезло, и я натолкнулся на Ubuntu на обоих моих ноутбуках.

5
задан 25 September 2017 в 19:40

6 ответов

Как правило, вы пытаетесь назвать как можно меньше команд, но в вашем случае я думаю, что это вопрос вкуса - я бы пошел с -exec, используя его так:

find . -name '*.flac' -exec bash -c 'ffmpeg -i "$0" "${0%flac}mp3" && rm "$0"' {} \;

Фокус в том, чтобы вызвать bash с опцией -c, таким образом вы можете не только выполнять несколько команд, но также использовать Bash Parameter Substitution, чтобы удалить flac, заканчивающийся от ваших имен файлов, - я полагаю, вы действительно не хотите в конечном итоге с файлами с именем filename.flac.mp3, вы?

Пояснения

bash -c '…' {} - запустите команду (ы) … в bash с именем файла как первый аргумент (доступный с $0) ${0%flac} - полоса flac с конца имени файла && rm "$0" - только если предыдущая команда выполнена успешно, удалите исходный файл
4
ответ дан 18 July 2018 в 06:17

Поскольку Zanna и десерт уже ответили -exec, предпочтительнее, когда xargs не является необходимым («Обычно мы не призываем дополнительную программу, если она не дает никаких дополнительных преимуществ с точки зрения надежности, производительности или читабельности. ")

Хотя это совершенно правильно, я хочу добавить, что xargs в сочетании с флагом -P может обеспечить существенное преимущество с точки зрения производительности.

xargs будет генерировать параллельные процессы, позволяя многопоточность, аналогичную, но более гибкую, чем команда parallel.

-P max-procs, --max-procs=max-procs Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; other‐ wise chances are that only one exec will be done. [...]

Это особенно помогает с процессами, которые не запускаются многопоточными с помощью самих себя. В вашем случае ffmpeg позаботится о многопоточности, поэтому это не поможет или даже отрицательно скажется на производительности.

find . -name "*.ext" -print0 | xargs -0 -i -P 20 command -in {} -out {}.out
2
ответ дан 18 July 2018 в 06:17

резюме:

если Вы больше знакомы с на [F11], чем -exec, вы, вероятно, хотите использовать [от f13] при использовании find.

С [С f15] это отдельная программа, призвание это, вероятно, будет намного менее эффективным, чем использование -exec, что является особенностью [f17 в] программы. Мы обычно не хочу назвать дополнительную программу, если она не дает никаких дополнительных преимуществ в отношении надежности, производительности и читабельности. С find ... -exec ... обеспечивает возможность выполнения команд со списком аргументов (как [зг19] никак) если можно, здесь нет какого-то из преимуществ использования xargs с [клавиши f21] за -exec. В случае ffmpeg, мы должны определить входные и выходные файлы, поэтому мы не можем гарантировать прирост производительности, используя либо метод построения списка аргументов и xargs удаление нелогично Оригинальное расширение-это сложнее.

, что [f25 привод датчика] не

Примечание: подробный флаг (который печатает построил команду с аргументами) в xargs это -t, и интерактивные флаг (которая вызывает у пользователя будет запрошено подтверждение для работы на каждый параметр), -p. Вы можете найти оба этих полезных для понимания и тестирования своего поведения.

xargs попытки превратить его stdin (как правило, в стандартный вывод предыдущей команды, которая была передается ему) в список аргументов какую-то команду.

command1 | xargs command2 [output of command1 will be appended here]

, поскольку стандартный вывод или стандартный поток ввода просто поток текста (это также, почему Вы не должны анализировать выход [f30 с]), xargs легко подставляли. Он читает аргументы как разделенных пробелами или новыми строками. Имена файлов могут содержать пробелы и могут даже содержать символы новой строки, и таких файлов приведет к непредсказуемому поведению. Допустим у вас есть файл под названием [f32 из]. Когда список, содержащий это имя передается в xargs, он пытается запустить данную команду на foo и на bar.

та же проблема возникает при вводе [f36 В], А вы знаете, что можете избежать это, цитируя пространство или целое слово, например [fунции f37] или command "foo bar", но даже если мы могл закавычить список прошедших в [f39 расстройства] мы обычно не хотим, потому что мы не хотим, чтобы весь этот список следует рассматривать как один аргумент. Стандартным решением этой проблемы является использование нулевой символ в качестве разделителя, так как имена файлов не могут содержать его:

find path test(s) -print0 | xargs -0 command

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

проблемы могут возникать, если команда не принимает несколько аргументов, или если список аргументов-это очень долго.

в этом случае, если вы используете ffmpeg, которая ожидает ввода файлов должна быть указана первой, и выходной файл должен быть указан последним. Мы можем сказать ffmpeg какие файлы(ы), чтобы явно использовать в качестве входных данных с [пулемет f44] флаг, но мы должны дать Имя файла для вывода (из которых формата обычно догадались, хотя мы можем также указать его) тоже. Итак, для построения любой команды, вы должны использовать опцию заменить строку ([f45 с] или -i) из xargs, чтобы указать входной и выходной файлы:

... | xargs -I{} command {} {}.out

(в документации сказано, что -i является устаревшей для этой цели, и мы должны использовать -I, но я не уверен, почему. При использовании -I, Вам необходимо указать замены ({} обычно используется) сразу после выбора. С -i можно не указывать замены, но {} понимается по умолчанию.)

в -I опция заставляет команду список должен быть разделен только на переводы строк, пробелы не допускаются, поэтому если вы уверены, что ваши имена не будут содержать переводы строк, Вы не должны использовать [f55, которая] при использовании -I. Если Вы не уверены, вы все еще можете использовать более безопасные синтаксис:

find -name "*.flac" -print0 | xargs -0I{} ffmpeg -i {} {}.mp3

однако, в бенефис xargs (которая позволяет выполнить команду один раз со списком аргументов) теряется здесь, так как ffmpeg должна выполняться один раз для каждой пары входных и выходных файлов (вы можете увидеть это легко путем добавления echo, чтобы [от f60], чтобы проверить вышеуказанные команды). Это также производит нелогично именем и не позволит вам запустить несколько команд. Чтобы сделать последнее, вы можете позвонить bash, а в ответ десерт:

... | xargs -I{} bash -c 'ffmpeg -i {} {}.mp3 && rm {}' [dиода d17]но ответа переименование десерт.[!dиода d17]

как -exec разные

при использовании параметра -exec в [64-го фокуса], найденные файлы передаются как аргументы команды после [камера f65]. Они не превратились в текст. С синтаксисом:

find ... -exec command {} \;

command выполняется один раз для каждого найденного файла. С синтаксисом

find ... -exec command {} +

список аргументов конструируется из найденных файлов, так что мы можем выполнить команду только один раз (или столько раз, сколько потребуется) на несколько файлов, дает благо производительности xargs. Однако, поскольку доводы именем не построены из потока текста, используя [f68 не] не проблема xargs имеет повреждения на пробелы и другие специальные символы.

с [р70], мы не можем использовать + по той же причине, что и xargs не дали бенефис; поскольку нам нужно указать вход и выход, то команда должна выполняться для каждого файла в отдельности. Мы должны использовать некоторую форму

find -name "*.flac" -exec ffmpeg -i {} {}.out \;

это, опять же, дадут вам довольно нелогично имени файла, в качестве десерта ответ объясняет, так что вы, возможно, захотите лишить его, как десерт ответе объясняется, как сделать с строка манипуляции (не легко сделать в xargs; еще одна причина, чтобы использовать -exec). Он также объясняет, как выполнить несколько команд в файл, так что вы можете безопасно удалить исходный файл после успешного преобразования.

вместо того, чтобы повторять десерт по рекомендации, с которыми я согласен, я предлагаю альтернативу [f75 в Джей], что позволяет гибкость для запуска bash -c после [f77 на английском языке]; вечеринки for цикл:

[F9] и

удалить echoЭс после тестирования на самом деле работать с файлами.

ffmpeg не хватает --, чтобы отметить конец вариантов, поэтому, чтобы избежать именами файлов, начинающимися с - интерпретируются как функции, мы используем ./ для указания текущего каталога, а не начиная с **, так что все пути начинаются с ./, а не произвольные имена. Это означает, что мы не должны использовать -- с rm (которая не признает его) либо.

аргументы: вам следует привести свой -name тест выражение, если оно содержит какие-либо символы, в противном случае оболочка будет расширяться их, если это возможно (т. е. если они соответствуют все файлы в текущем каталоге), прежде чем они передаются find, поэтому в первую очередь, использовать

find -name "*.flac"

для предотвращения неожиданного поведения.

7
ответ дан 18 July 2018 в 06:17

Как правило, вы пытаетесь назвать как можно меньше команд, но в вашем случае я думаю, что это вопрос вкуса - я бы пошел с -exec, используя его так:

find . -name '*.flac' -exec bash -c 'ffmpeg -i "$0" "${0%flac}mp3" && rm "$0"' {} \;

Фокус в том, чтобы вызвать bash с опцией -c, таким образом вы можете не только выполнять несколько команд, но также использовать Bash Parameter Substitution, чтобы удалить flac, заканчивающийся от ваших имен файлов, - я полагаю, вы действительно не хотите в конечном итоге с файлами с именем filename.flac.mp3, вы?

Пояснения

bash -c '…' {} - запустите команду (ы) … в bash с именем файла как первый аргумент (доступный с $0) ${0%flac} - полоса flac с конца имени файла && rm "$0" - только если предыдущая команда выполнена успешно, удалите исходный файл
4
ответ дан 24 July 2018 в 18:34

Поскольку Zanna и десерт уже ответили -exec, предпочтительнее, когда xargs не является необходимым («Обычно мы не призываем дополнительную программу, если она не дает никаких дополнительных преимуществ с точки зрения надежности, производительности или читабельности. ")

Хотя это совершенно правильно, я хочу добавить, что xargs в сочетании с флагом -P может обеспечить существенное преимущество с точки зрения производительности.

xargs будет генерировать параллельные процессы, позволяя многопоточность, аналогичную, но более гибкую, чем команда parallel.

-P max-procs, --max-procs=max-procs Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; other‐ wise chances are that only one exec will be done. [...]

Это особенно помогает с процессами, которые не запускаются многопоточными с помощью самих себя. В вашем случае ffmpeg позаботится о многопоточности, поэтому это не поможет или даже отрицательно скажется на производительности.

find . -name "*.ext" -print0 | xargs -0 -i -P 20 command -in {} -out {}.out
2
ответ дан 24 July 2018 в 18:34

резюме:

если Вы больше знакомы с на [F11], чем -exec, вы, вероятно, хотите использовать [от f13] при использовании find.

С [С f15] это отдельная программа, призвание это, вероятно, будет намного менее эффективным, чем использование -exec, что является особенностью [f17 в] программы. Мы обычно не хочу назвать дополнительную программу, если она не дает никаких дополнительных преимуществ в отношении надежности, производительности и читабельности. С find ... -exec ... обеспечивает возможность выполнения команд со списком аргументов (как [зг19] никак) если можно, здесь нет какого-то из преимуществ использования xargs с [клавиши f21] за -exec. В случае ffmpeg, мы должны определить входные и выходные файлы, поэтому мы не можем гарантировать прирост производительности, используя либо метод построения списка аргументов и xargs удаление нелогично Оригинальное расширение-это сложнее.

, что [f25 привод датчика] не

Примечание: подробный флаг (который печатает построил команду с аргументами) в xargs это -t, и интерактивные флаг (которая вызывает у пользователя будет запрошено подтверждение для работы на каждый параметр), -p. Вы можете найти оба этих полезных для понимания и тестирования своего поведения.

xargs попытки превратить его stdin (как правило, в стандартный вывод предыдущей команды, которая была передается ему) в список аргументов какую-то команду.

command1 | xargs command2 [output of command1 will be appended here]

, поскольку стандартный вывод или стандартный поток ввода просто поток текста (это также, почему Вы не должны анализировать выход [f30 с]), xargs легко подставляли. Он читает аргументы как разделенных пробелами или новыми строками. Имена файлов могут содержать пробелы и могут даже содержать символы новой строки, и таких файлов приведет к непредсказуемому поведению. Допустим у вас есть файл под названием [f32 из]. Когда список, содержащий это имя передается в xargs, он пытается запустить данную команду на foo и на bar.

та же проблема возникает при вводе [f36 В], А вы знаете, что можете избежать это, цитируя пространство или целое слово, например [fунции f37] или command "foo bar", но даже если мы могл закавычить список прошедших в [f39 расстройства] мы обычно не хотим, потому что мы не хотим, чтобы весь этот список следует рассматривать как один аргумент. Стандартным решением этой проблемы является использование нулевой символ в качестве разделителя, так как имена файлов не могут содержать его:

find path test(s) -print0 | xargs -0 command

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

проблемы могут возникать, если команда не принимает несколько аргументов, или если список аргументов-это очень долго.

в этом случае, если вы используете ffmpeg, которая ожидает ввода файлов должна быть указана первой, и выходной файл должен быть указан последним. Мы можем сказать ffmpeg какие файлы(ы), чтобы явно использовать в качестве входных данных с [пулемет f44] флаг, но мы должны дать Имя файла для вывода (из которых формата обычно догадались, хотя мы можем также указать его) тоже. Итак, для построения любой команды, вы должны использовать опцию заменить строку ([f45 с] или -i) из xargs, чтобы указать входной и выходной файлы:

... | xargs -I{} command {} {}.out

(в документации сказано, что -i является устаревшей для этой цели, и мы должны использовать -I, но я не уверен, почему. При использовании -I, Вам необходимо указать замены ({} обычно используется) сразу после выбора. С -i можно не указывать замены, но {} понимается по умолчанию.)

в -I опция заставляет команду список должен быть разделен только на переводы строк, пробелы не допускаются, поэтому если вы уверены, что ваши имена не будут содержать переводы строк, Вы не должны использовать [f55, которая] при использовании -I. Если Вы не уверены, вы все еще можете использовать более безопасные синтаксис:

find -name "*.flac" -print0 | xargs -0I{} ffmpeg -i {} {}.mp3

однако, в бенефис xargs (которая позволяет выполнить команду один раз со списком аргументов) теряется здесь, так как ffmpeg должна выполняться один раз для каждой пары входных и выходных файлов (вы можете увидеть это легко путем добавления echo, чтобы [от f60], чтобы проверить вышеуказанные команды). Это также производит нелогично именем и не позволит вам запустить несколько команд. Чтобы сделать последнее, вы можете позвонить bash, а в ответ десерт:

... | xargs -I{} bash -c 'ffmpeg -i {} {}.mp3 && rm {}' [dиода d17]но ответа переименование десерт.[!dиода d17]

как -exec разные

при использовании параметра -exec в [64-го фокуса], найденные файлы передаются как аргументы команды после [камера f65]. Они не превратились в текст. С синтаксисом:

find ... -exec command {} \;

command выполняется один раз для каждого найденного файла. С синтаксисом

find ... -exec command {} +

список аргументов конструируется из найденных файлов, так что мы можем выполнить команду только один раз (или столько раз, сколько потребуется) на несколько файлов, дает благо производительности xargs. Однако, поскольку доводы именем не построены из потока текста, используя [f68 не] не проблема xargs имеет повреждения на пробелы и другие специальные символы.

с [р70], мы не можем использовать + по той же причине, что и xargs не дали бенефис; поскольку нам нужно указать вход и выход, то команда должна выполняться для каждого файла в отдельности. Мы должны использовать некоторую форму

find -name "*.flac" -exec ffmpeg -i {} {}.out \;

это, опять же, дадут вам довольно нелогично имени файла, в качестве десерта ответ объясняет, так что вы, возможно, захотите лишить его, как десерт ответе объясняется, как сделать с строка манипуляции (не легко сделать в xargs; еще одна причина, чтобы использовать -exec). Он также объясняет, как выполнить несколько команд в файл, так что вы можете безопасно удалить исходный файл после успешного преобразования.

вместо того, чтобы повторять десерт по рекомендации, с которыми я согласен, я предлагаю альтернативу [f75 в Джей], что позволяет гибкость для запуска bash -c после [f77 на английском языке]; вечеринки for цикл:

[F9] и

удалить echoЭс после тестирования на самом деле работать с файлами.

ffmpeg не хватает --, чтобы отметить конец вариантов, поэтому, чтобы избежать именами файлов, начинающимися с - интерпретируются как функции, мы используем ./ для указания текущего каталога, а не начиная с **, так что все пути начинаются с ./, а не произвольные имена. Это означает, что мы не должны использовать -- с rm (которая не признает его) либо.

аргументы: вам следует привести свой -name тест выражение, если оно содержит какие-либо символы, в противном случае оболочка будет расширяться их, если это возможно (т. е. если они соответствуют все файлы в текущем каталоге), прежде чем они передаются find, поэтому в первую очередь, использовать

find -name "*.flac"

для предотвращения неожиданного поведения.

7
ответ дан 24 July 2018 в 18:34
  • 1
    Это отличный ответ, большое вам спасибо! OP задал второй вопрос, который вы не указали до сих пор: Если бы я хотел одновременно удалить исходный файл, как бы добавить вторую команду в код выше? – dessert 25 September 2017 в 13:59
  • 2
    @dessert спасибо и amp; спасибо за указание на это :) Так как ваш ответ дает лучший способ с find imho, я добавил альтернативу для запуска нескольких команд – Zanna 25 September 2017 в 14:28
  • 3
    ", если он не дает каких-либо дополнительных преимуществ в отношении [...] производительности" : Вот где я хотел бы добавить xargs -P, который я использую очень часто, чтобы ускорить работу много, и, насколько мне известно, с -exec невозможно. – RoVo 25 September 2017 в 15:05
  • 4
    @RoVo, что интересно - надеюсь, вам хочется добавить ответ об этом :) – Zanna 25 September 2017 в 15:10

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

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