df
не покажет пространство, зарезервированное для root
(даже когда выполнено как root
):
# df -h
Filesystem Size Used Avail Use% Mounted on
...
/dev/optvol 625G 607G 0 100% /opt
...
Уменьшите зарезервированное пространство до 4%
# tune2fs -m4 /dev/sda4
df -h
теперь показал 45M свободный.
Отложите его к 5%
# tune2fs -m5 /dev/sda4
-exec
предикат, который выполняет команду (не оболочка) и оценивает к TRUE или FALSE на основе результата команды (нулевой или ненулевой статус выхода).
Так:
find . -iname '*.csv' -exec grep foo {} \; -print
распечатал бы путь к файлу если grep
находит нечто в файле. Вместо -print
можно использовать другого -exec
предикат или любой другой предикат
find . -iname '*.csv' -exec grep foo {} \; -exec echo {} \;
См. также !
и -o
найдите операторы для отрицания и или.
С другой стороны, можно запустить оболочку как:
find . -iname '*.csv' -exec sh -c '
grep foo "$1" && echo "$1"' sh {} \;
Или избегать необходимости запускать оболочку для каждого файла:
find . -iname '*.csv' -exec sh -c '
for i do
grep foo "$i" && echo "$i"
done' sh {} +
Проблема, с которой Вы сталкиваетесь, состоит в том, что оболочка сначала анализирует командную строку и видит две простых команды, разделенные &&
оператор: find . -iname \*.csv -exec grep foo {}
, и echo {} \;
. Заключение в кавычки &&
(find . -iname \*.csv -exec grep foo {} '&&' echo {} \;
) обходы, что, но теперь команда, выполняемая find
что-то как grep
с аргументами foo
, wibble.csv
, &&
, echo
и wibble.csv
. Необходимо сообщить find
выполнять оболочку, которая интерпретирует &&
оператор:
find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;
Обратите внимание что первый аргумент после sh -c SOMECOMMAND
$0
, нет $1
.
Можно сэкономить время запуска процесса оболочки для каждого файла путем группировки вызовов команды с -exec … +
. Для простоты обработки передайте некоторое фиктивное значение как $0
так, чтобы "$@"
перечисляет имена файлов.
find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +
Если команда оболочки является всего двумя программами, разделенными &&
, find
может сделать задание отдельно: запишите два последовательных -exec
действия и второе будут только выполняться, если первый выйдет с состоянием 0.
find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;
(Я принимаю это grep
и echo
только для цели иллюстрации, как -exec echo
может быть заменен -print
и получающийся вывод не особенно полезен так или иначе.)
./some-file: grep: command not found
сообщение об ошибке. -exec find sh -c '... "$1"' sh {} \;
не имел бы проблемы. Существует опечатка (связанная) в Вашей второй команде находки.
– Stéphane Chazelas
14.11.2012, 11:31
В этом конкретном случае я сделал бы:
find . -iname \*.csv -exec grep -l foo \{\} \;
Или если у Вас есть ack:
ack -al -G '.*\.csv' foo
Для ответа на фактический вопрос что-то вроде этого может работать:
find . -iname \*.csv -exec sh -c "grep foo {} && echo {}" \;