Я пытаюсь выполнить несколько команд для вещей, которые я нашел, как я могу добиться этого?
find . -exec cmd1; cmd2
не похоже на работу; вместо этого он запускает cmd2 после того, как cmd1 был выполнен для каждого файла.
Я пытаюсь выполнить несколько команд для вещей, которые я нашел, как я могу добиться этого?
find . -exec cmd1; cmd2
не похоже на работу; вместо этого он запускает cmd2 после того, как cmd1 был выполнен для каждого файла.
Ответы:
В этой демонстрации я буду использовать sh -c 'echo first; false'
(или true
) для первого -exec
. Это даст некоторый вывод, а также будет иметь эффект выбранного кода выхода. Затем echo second
будет использован для второго. Предположим, что в текущем каталоге есть один файл.
$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
Настоящая команда такого типа будет выглядеть так:
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
Во втором наборе экранированные скобки объединяют два -exec
предложения. -false
Между ними заставляет тест состояние на «ложь» , и -o
приводит к следующему выражению (второй -exec
) , чтобы оценить из-за -false
.
От man find
:
expr1 expr2
Два выражения в строке берутся с подразумеваемыми "и"; expr2 не оценивается, если expr1 имеет значение false.expr1 -a expr2
То же, что expr1 expr2.expr1 -o expr2
или; expr2 не оценивается, если expr1 имеет значение true.
Если вам не важно, что cmd1 может предотвратить запуск cmd2 из-за кода ошибки 0
:
find . -exec cmd1 \; -exec cmd2 \;
Единственный надежный способ заставить обе команды всегда запускаться, это find
вызвать оболочку, которая впоследствии будет запускать команды в последовательности:
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Если вы не против создать скрипт, который выполняет cmd1 и cmd2, то это просто так:
find . -exec myscript {} \;
или же
find . -exec myscript {} +
Использовать \; или + в зависимости от того, может ли myscript обрабатывать более одного файла за раз (становится проблематично, если в именах файлов есть пробелы и т. д.).
По моему опыту, включение того, что вы делали в сценарий, почти всегда стоило того. Если вам придется сделать это один раз, вам придется сделать это снова.
Но ловкий трюк, чтобы поместить находку внутри сценария:
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Затем myscript работает с любыми файлами, которые вы предоставляете в качестве аргументов для работы, но если вы не предоставите ему никаких аргументов, он запускает find из текущего каталога и затем вызывает себя для найденных файлов. Это обходит тот факт, что find -exec не может вызывать функции оболочки, которые вы определили в своем скрипте.
Я пробовал оба предыдущих решения без особой удачи. Этот работал хорошо для меня:
$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done
попробуйте команду:
sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l
*
В -exec
части будет расширяться на все файлы в текущем каталоге. Особенно когда работает как sudo
.
-o
.