Когда я запускаю эту команду в Терминале:

find . -type f -name "*.png" -exec sh -c "file {} | egrep -o '^.*\d+,'" \;

Я получаю эту ошибку, если имя файла содержит круглые скобки:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `file ./(terrible filename).png | egrep -o '^.*\d+,''

Я знаю, что это как-то связано с sh -c, но я не знаю, как это исправить, спасибо.

./( ужасное имя файла) .png: данные изображения PNG, 512 x 512, // trying to get this result

1
Cocoa Puffs 29 Дек 2015 в 13:08

2 ответа

Лучший ответ

Вы просто вставляете имя файла в sh -c '...' без каких-либо кавычек. Строка внутри sh -c после подстановок, сделанных find, должна иметь допустимый синтаксис sh, что означает, что не может быть одинарных кавычек, круглых скобок и т. Д. Без кавычек.

Более надежный подход - использовать -exec file {} и передавать весь вывод из find в egrep.

find . -type f -name "*.png" -exec file {} \; | egrep -o '^.*\d+,'

Маркер-заполнитель {} заменяется на find с именем файла, обрабатываемого в данный момент. Когда это одиночный токен, find может передавать любое имя файла; но если вы интерполируете его в более длинную строку, такую как команду оболочки, вам нужно будет убедиться, что все необходимые кавычки и т. д. добавлены как-то. Это беспорядочно, поэтому обычно вам нужно найти решение, в котором вам не нужно этого делать.

(Как указано в комментариях к другому ответу, -exec sh -c 'file "$1"' _ {} \; - это еще один способ добиться этого; это обобщается на произвольно сложные команды оболочки. Если ваш find поддерживает exec {} \+ вы хотите добавить простой цикл: -exec sh 'for f; do file "$f"; done' _ {} \+ - кстати, _ - фиктивный заполнитель для $0.)

4
Community 23 Май 2017 в 11:44

Есть ли круглые скобки в именах файлов? Это может помочь:

find . -type f -name "*.png" -exec sh -c "file '{}' | egrep -o '^.*\d+,'" \;
0
Jens 29 Дек 2015 в 10:13