Помогите понять синтаксис `find` в Solaris

Помогите понять синтаксис `find` в Solaris

Рассмотрим следующие файлы:

$ find findtest                     
findtest
findtest/test1
findtest/test1/start.ksh
findtest/test2
findtest/test2/start.ksh
findtest/test3
findtest/test3/start.ksh
findtest/test4
findtest/test4/start.ksh

Мой вопрос касается использования {}в -execвызове. Он работает так, как я и ожидал, при обозначении файла результата:

$ find findtest -name test[1-4] -exec ls -d {} \;           
findtest/test1
findtest/test2
findtest/test3
findtest/test4

Однако, похоже, он не расширяется при использовании в пути:

$ find findtest -name test[1-4] -exec md5sum {}/start.ksh \;     
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory

Как я могу использовать find -type d -execдля доступа к файлам более низкой иерархии? Я знаю, что могу использовать forтакой цикл, но мне интересно узнать, можно ли это сделать за один findвызов:

$ for f in $(find findtest -name test[1-4]); do md5sum "$f"/start.ksh; done
d41d8cd98f00b204e9800998ecf8427e  findtest/test1/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test2/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test3/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test4/start.ksh

решение1

TheСтандарт POSIX для команды findтребует только замены изолированного {} на имя файла, и только первого. Использование {}/start.kshприводит к неопределенному поведению.

Аргумент, содержащий только два символа "{}", должен быть заменен набором агрегированных имен путей, при этом каждое имя пути должно передаваться как отдельный аргумент вызываемой утилите в том же порядке, в котором оно было агрегировано. Размер любого набора из двух или более имен путей должен быть ограничен таким образом, чтобы выполнение утилиты не приводило к превышению системного ограничения {ARG_MAX}. Если присутствует более одного аргумента, содержащего только два символа "{}", поведение не определено.

Если строка utility_name или аргумента содержит два символа «{}», а не только два символа «{}», то реализацией определяется, заменяет ли find эти два символа или использует строку без изменений.

Одним из способов сделать то, что вам нужно, с помощью Solaris find, является следующая команда:

find findtest -name "test[1-4]" -exec sh -c 'md5sum $1/start.ksh' foo {} \;

Более быстрый способ:

find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} + 

решение2

  1. На самом деле ваша оболочка расширяется test[1-4]до того, как она вызовет find. Вам нужно экранировать ее с помощью'…'
  2. {}рассматривается как шаблон только тогда, когда он является отдельным токеном

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

Я знаю, что можно использовать такой цикл for, но мне интересно, можно ли это сделать за один вызов find:

find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh'— работает md5sumэффективно — все имена файлов выдаются одновременно.

Связанный контент