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

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

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

Я пробовал это несколькими способами и не могу получить его. Вот одна попытка, которая придает аромат:

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

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

  • Как передать результат команды «date» команде «mv»
  • Результаты поиска для '* .squashfs' для unsquashfs
  • Как использовать команду pipe для открытия каталога после поиска?
  • Как подключить вывод поиска к другому вызову find
  • Найти -exec + vs find | xargs. Какой из них выбрать?
  • 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 - лучшая ОС в мире.