Иногда я вижу следующую команду:
find . -name * -exec ls -a {} \;
Меня попросили выполнить это.
Что {} \;
значит здесь?
command-line
find
codeofnode
источник
источник
-name *
избыточно-name *
это хуже, чем избыточно. Поскольку*
кавычка не заключена в кавычки, оболочка расширяет ее до списка имен файлов в текущей папке, с пробелами, которые обрабатываются некорректно, что приводит к непредвиденным результатам или сообщению об ошибке. В качестве дополнительного пункта,find
имеет много функций, одна из которых заключается в перечислении файлов; это позволяет избежать необходимости использовать-exec
. Например, вы можете использоватьfind . -print
илиfind . -ls
. Наконец, есть два пути , чтобы избежать запятой: либо , как вы сделали с обратным косыми чертами,\;
или процитировать:';'
. Используйте то, что вам удобнее.Ответы:
Если вы запускаете
find
сexec
,{}
расширяется до имени файла каждого файла или каталога, найденного с помощьюfind
(так чтоls
в вашем примере получает каждое найденное имя файла в качестве аргумента - обратите внимание, что оно вызываетls
или любую другую команду, указанную вами один раз для каждого найденного файла).Точка с запятой
;
завершает команду, выполненнуюexec
. Его необходимо экранировать,\
чтобы оболочка,find
внутри которой вы работаете , не воспринимала его как свой собственный специальный символ, а передавала егоfind
.Смотрите эту статью для более подробной информации.
Кроме того,
find
обеспечивает некоторую оптимизацию с помощьюexec cmd {} +
- при таком запускеfind
добавляет найденные файлы в конец команды, а не вызывает ее один раз для каждого файла (так что команда запускается только один раз, если это возможно).Разница в поведении (если не в эффективности) легко заметна, если запустить с
ls
, например,Предполагая, что у вас есть несколько
jpg
файлов (с достаточно короткими путями ), результатом является одна строка на файл в первом случае и стандартноеls
поведение отображения файлов в столбцах для последнего.источник
\;
с+
.find . -name * | ls -a -
?find
. Кроме того, выводls
в этом случае, очевидно, не зависит от ввода - независимо от того, что я использую в качестве фильтраfind
,ls
просто отображает содержимое рабочего каталога и все. Проверьте, например,find ~ -iname '*.jpg' -exec ls -a {} \;
противfind ~ -iname '*.jpg' | ls -a
.echo 'foo' | ls -a
.-
в своейls -a -
команде, когда проверяли, что запрашивает @ dr-h.С man-страницы для
find
команды :Итак, вот объяснение:
{}
означает «выводfind
». Как и в «все, чтоfind
найдено».find
возвращает путь к файлу, который вы ищете, верно? Так что{}
заменяет его; это заполнитель для каждого файла, которыйfind
находит команда (взято отсюда ).\;
Часть в основном говоритfind
«хорошо, я сделал с командой я хотел выполнить».Пример:
Допустим, я нахожусь в каталоге, полном
.txt
файлов. Затем я запускаю:Первая часть,
find . -name *.txt
возвращает список.txt
файлов. Вторая часть-exec cat {} \;
будет выполнятьcat
команду для каждого файла , найденногоfind
, такcat file1.txt
,cat file2.txt
и так далее.источник
*.txt
должна быть указана как'*.txt'
. Это потому, что если.txt
в текущей папке есть файлы, оболочка раскроет это, и вы получите неправильные результаты или сообщение об ошибке.find -name '*.txt' -exec cat {} \;