Интересная проблема. Вот то, что я сделал бы:
После того, как это сделано, необходимо будет обновить загрузчик. Принятие Вы используете GRUB, монтируют недавно записанный раздел затем chroot в него и работают update-grub
(будьте осторожны, хотя, Вы, возможно, должны скорректировать его файлы конфигурации, прежде чем это будет работать правильно).
Удачи!
POSIXLY:
find . -type f -exec sh -c '
for f do
: command "$f"
done
' sh {} +
С find
поддержки -print0
и xargs
поддержки -0
:
find . -type f -print0 | xargs -0 <command>
-0
опция говорит, что xargs для использования символа ASCII NUL вместо пространства для окончания (разделяют) имена файлов.
Пример:
find . -maxdepth 1 -type f -print0 | xargs -0 ls -l
Используя -print0
одна опция, но не вся поддержка программ с помощью nullbyte-разграниченных потоков данных, таким образом, необходимо будет использовать xargs
с -0
опция для некоторых вещей, как ответ Gnouc отметил.
Альтернатива должна была бы использовать find
-exec
или -execdir
опции. Первое из следующего подаст имена файлов к somecommand
по одному, в то время как второе расширится до списка файлов:
find . -type f -exec somecommand '{}' \;
find . -type f -exec somecommand '{}' +
Можно найти, что Вы - более обеспеченное использование globbing во многих случаях. Если у Вас есть современная оболочка (колотите 4 +, zsh, ksh), можно получить рекурсивный globbing с globstar
(**
). В ударе необходимо установить это:
shopt -s globstar
somecommand ./**/*.txt ## feeds all *.txt files to somecommand, recursively
У меня есть высказывание строки shopt -s globstar extglob
в моем .bashrc, таким образом, это всегда включается для меня (и так расширенные шарики, которые также полезны).
Если Вы не хотите рекурсивности, очевидно, просто используйте ./*.txt
вместо этого, для использования каждого *.txt в рабочем каталоге. find
имеет некоторые очень полезные мелкомодульные возможности поиска и обязателен для десятков тысяч файлов (в которой точке Вы столкнетесь с максимальным количеством оболочки аргументов), но для ежедневного использования это является часто ненужным.
Лично, я использовал бы -exec
найдите, что действие решает этот вид проблемы. Или, при необходимости, xargs
, который допускает параллельное выполнение.
Однако существует способ добраться find
произвести читаемый ударом список имен файлов. Неудивительно, это использует -exec
и bash
, в особенности расширение printf
команда:
find ... -exec bash -c 'printf "%q " "$@"' printf {} ';'
Однако, в то время как это распечатает правильно оставленные из оболочки слова, это не будет применимо с $(...)
, потому что $(...)
не интерпретирует кавычки или Escape. (resut $(...)
подвергается разделению слова и расширению пути, если не окружено кавычками.), Таким образом, следующее не сделает то, что Вы хотите:
ls $(find ... -exec bash -c 'printf "%q " "$@"' printf {} +)
То, что необходимо было бы сделать:
eval "ls $(find ... -exec bash -c 'printf "%q " "$@"' printf {} +)"
(Обратите внимание, что я не предпринял реальной попытки протестировать вышеупомянутое чудовище.)
Но затем Вы могли бы также сделать:
find ... -exec ls {} +
ls
сценарий соответственно получает вариант использования OP, но это - только предположение, так как нас не показали то, что он на самом деле пытается выполнить. Это решение на самом деле работает очень приятно; я получаю вывод I (неопределенно) ожидаемый для всех забавных имен файлов, включая которые я попробовал, touch "$(tr a-z '\001-\026' <<<'the quick brown fox jumped over the lazy dogs')"
– tripleee
03.07.2013, 14:17
eval
это, Вы не должны передавать его eval
все же; Вы могли сохранить его в параметре и использовать его позже, возможно, несколько раз с различными командами. Однако OP не дает признака, что это - вариант использования (и если бы это было, то могло бы быть лучше поместить имена файлов в массив, хотя это хитро также.)
– rici
03.07.2013, 17:33
find ./ | grep " "
получит файлы и каталоги, содержащие пробелы
find ./ -type f | grep " "
получите файлы, содержащие пробелы
find ./ -type d | grep " "
получите каталоги, содержащие пробелы
Таким образом, если вы не хотите использовать xargs
(, скорее всего, ни, например. parallel
), вывод find
может быть прочитан и обработан построчно следующим образом:
find. -type f | while read x; do
# do something with $x
done
При установке внутреннего разделителя полей на новую строку оболочка будет игнорировать пробелы:
IFS=$'\n' eval 'for i in `find. -type f -name "*"`;do echo $i;done'
Если все, что вы хотите, это избежать пробелов, вы можете сделать это:
find (...) | sed -e's/ /\\ /g' | whatever...
Но, насколько я знаю, такой обработки требует только xargs. Например:
find. -type f -name '* *' | sed -e's/ /\\ /g' | xargs ls -l
Это может сработать для вас. Он не избегает ничего, кроме пробелов, но охватывает самый обычный случай. Кавычки в именах файлов все еще могут быть проблемой.
ls $(find . -maxdepth 1 -type f -print0 | xargs -0)
Я добираюсьls: cannot access ./foo: No such file or directory
ls: cannot access bar: No such file or directory
– bug 01.07.2013, 19:01$(..)
в двойных кавычках"$(..)"
– evilsoup 01.07.2013, 19:03find
иxargs
. – cuonglm 01.07.2013, 19:12