найдите тайны: не может заставить канал работать в - исполнительная строка

нет ни одного, но:

setenv название команды в *csh семейство оболочек

export название команды в "другом" семействе оболочек (пепел, граница, граница снова, zsh)

и, хорошо, синтаксис немного отличается. но кроме этого?ничего.

4
02.04.2011, 00:55
2 ответа

Я не уверен, что у Вас может быть канал внутри -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 ./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 появляется где угодно кроме конца имени файла, он не изменяется.

8
27.01.2020, 20:49
  • 1
    Ничего себе, спасибо за подробный ответ. Ваши подсказки будут хорошей стартовой точкой к получению дополнительной информации о Bash, также. Очень ценивший. –  shanusmagnus 01.04.2011, 06:26
  • 2
    Пожалуйста. На техническом примечании, find -exec может только выполнить простые команды, не конвейеры. Это вызвано тем, что find вызовы exec, вместо system, таким образом, никакой синтаксис оболочки непосредственно не поддерживается. –  Mikel 01.04.2011, 07:03
  • 3
    Просто между прочим, я вполне уверен, что использование \0 как вход к циклу чтения избыточно, и что его цель состоит в том, чтобы позволить длинную строку командной строки (содержащий, многие \0 разграничили args) быть переданным программе, которая является \0 знающими разделителями и только названа однажды, но обрабатывает много args внутренне; каждый таким же образом... Это экономит много времени путем предотвращения, возможно, тысяч отдельных вызовов.... Нормальная новая строка хорошо для цикла чтения, если любые из имен файлов не имеют символ новой строки в них... Mhhh!?.. возможно, я только что убедил меня, что это - хорошая идея, в конце концов, :) –  Peter.O 01.04.2011, 17:55
  • 4
    последний один лайнер не ужасен, это - чистый художественный :-) –  Phil 23.01.2013, 11:37

Вы пытаетесь передать команду оболочки -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"' {} \; a find и идиома оболочки. Некоторые версии находки позволяют писать {} непосредственно в коде оболочки, но это - плохая идея, не только потому, что некоторые находят, что версии не делают, но также и потому что это может повредиться ужасно, если имя файла содержит специальные символы (например, кавычки). Таким образом, вместо этого имя файла передается оболочке как свой 0th аргумент, и сценарий использует переменную оболочки $0 относиться к файлу.
  • echo tiff_filename | sed s/tiff/jpg/ сложный, неэффективный, неправильный и хрупкий способ изменить имя файла. Это сложно и неэффективно, потому что Вы называете sed. Это неправильно, потому что Вы заменяете tiff где угодно в файле: например. tiffany.tiff стал бы jpgany.tiff. Это хрупко, потому что это не работало бы с некоторыми именами файлов (некоторые реализации echo обратные косые черты искажения). Вместо этого используйте ${0%.tiff} удалить .tiff суффикс от имени файла в $0.
1
27.01.2020, 20:49
  • 1
    Намного более чистый. Интересно, почему это находится в $0 вместо $1. –  Mikel 02.04.2011, 02:17
  • 2
    @Mikel: аргументы Процесса запускаются в 0, но первым аргументом (т.е. номер 0) является традиционно исполняемое имя, и оболочки не позволяют Вам выбрать его при выполнении команды. Но sh -c позволяет Вам выбрать $0 для сценария это - первый аргумент неопции. Это могло бы быть более чисто для записи sh -c 'process "$1"' sh {}. Мне нравится $0 в ситуациях как find -exec sh -c 'cp "$0" "$@"' "$destination" {} +, где Вам нужно одно слово плюс один список. –  Gilles 'SO- stop being evil' 02.04.2011, 02:35
  • 3
    Да, я предположил бы, что это запустится с $1, но Вы правы, это находится тут же в странице справочника. "Если существуют аргументы после строки, они присвоены позиционным параметрам, начиная с 0$". –  Mikel 02.04.2011, 03:46

Теги

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