find arcana: невозможно заставить трубу работать в линии -exec

Как я могу передать результаты поиска через sed для xform потока, а затем использовать этот преобразованный поток как один из двух аргументов для скрипта? IE:

find turn up file1.tiff (среди прочих)
sed transforms file1.tiff -> file1.jpg
команда выполняется с использованием обоих этих аргументов: convert file1.tiff file1.jpg

  • Как найти файлы с разрешениями больше, чем xxx, но игнорировать файлы с помощью SUID и SGID
  • Комбинация команды find и sed (редактор потока)
  • Как найти резервные файлы Emacs?
  • Как отображать «доступные для человека» размеры файлов в результатах поиска?
  • Как получить информацию о моих виртуальных рабочих столах через командную строку?
  • Найдите файл, в котором имя начинается с заглавной буквы
  • Я пробовал это несколькими способами и не могу получить его. Вот одна попытка, которая придает аромат:

    find ./out -regex ".*_p[bg]_.*tiff" -exec echo "Processing {}" \; -exec convert {} `echo {} | sed s/tiff/jpg/` \; 

    Я должен просто отказаться и написать скрипт на Python, чтобы делать каждую из этих частей отдельно, но я, наконец, пытаюсь изучить инструменты UNIX и теперь одержим. Помогите!

  • Как передать результат команды «date» команде «mv»
  • найти и найти: использование, плюсы и минусы друг друга
  • Найти исполняемые файлы рекурсивно
  • Найти: объединить -depth с -prune для кормления cpio
  • Как я могу искать файлы без определенных расширений в своих именах?
  • Как порядок аргументов влияет на скорость поиска
  • 2 Solutions collect form web for “find arcana: невозможно заставить трубу работать в линии -exec”

    Я не уверен, что у вас есть труба внутри -exec . find -exec echo {} \| sed s/tiff/jpg \; похоже, не работает.

    Если вы думаете, что ваш лучший вариант – сделать скрипт для преобразования, например

    convert_tiff_to_jpg :

     #!/bin/bash echo "Processing $1" convert "$1" "${1/%tiff/jpg}" 

    и назовите его, используя find -exec как вы и предполагали:

     find ./out -regex ".*_p[bg]_.*tiff" -exec convert_tiff_to_jpg {} \; 

    Есть несколько способов сделать это, используя find -print0 | xargs -0 find -print0 | xargs -0 , но все они довольно уродливы:

     find ./out -regex ".*_p[bg]_.*tiff" -print0 | while IFS= read -d $'\0' -r filename; do echo "Processing $filename" convert "$filename" "$(echo "$filename" | sed 's/tiff$/jpg/')" done 

    или

     find ./out -regex ".*_p[bg]_.*tiff" -print0 | while IFS= read -d $'\0' -r filename; do echo "Processing $filename" convert "$filename" "${filename/%tiff/jpg}" done 

    или

     find ./out -regex ".*_p[bg]_.*tiff" -print0 | xargs -0 -I FILE bash -c 'F="FILE"; echo "$F" "${F/%tiff/jpg}"' 

    Обратите внимание, что я изменил s/tiff/jpg на s/tiff$/jpg так что если tiff появляется где угодно, кроме конца имени файла, он не изменяется.

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

     find ./out -regex ".*_p[bg]_.*tiff" \ -exec sh -c 'echo "Processing $0"; convert "$0" "${0%.tiff}.jpg"' {} \; 
    • sh -c 'shell code, not using single quotes' – относительно распространенная идиома, когда вам нужны функции оболочки в контексте, ожидающем команды с аргументами.
    • -exec sh -c 'do stuff with "$0"' {} \; это идиома find и оболочки. Некоторые версии find позволяют записывать {} непосредственно внутри кода оболочки, но это плохая идея не только потому, что некоторые находки версий нет, но также и потому, что это может сильно испортиться, если имя файла содержит специальные символы (например, кавычки) , Поэтому вместо этого имя файла передается в оболочку как его 0-й аргумент, а скрипт использует переменную оболочки $0 для ссылки на файл.
    • echo tiff_filename | sed s/tiff/jpg/ echo tiff_filename | sed s/tiff/jpg/ – сложный, неэффективный, неправильный и хрупкий способ изменения имени файла. Это сложно и неэффективно, потому что вы вызываете sed. Это неправильно, потому что вы заменяете tiff любом месте файла: например, tiffany.tiff станет jpgany.tiff . Он хрупкий, потому что он не будет работать с некоторыми именами файлов (некоторые реализации echo кавычек обратных косых черт). Вместо этого используйте ${0%.tiff} чтобы удалить суффикс .tiff из имени файла в $0 .
    Linux и Unix - лучшая ОС в мире.