Bash: Как считать одну строку за один раз из вывода команды?

У меня есть процессор 430, 2GiB Celeron Ram. Под VirtualBox я использую VisualStudio, и все хорошо работает.

49
17.10.2012, 01:37
3 ответа

Существует ошибка, Вам нужно < <(command) нет <<<$(command)

< <( ) Замена Процесса, $() замена команды и <<< здесь-строка.

57
27.01.2020, 19:34
  • 1
    @RanRag, пытающаяся помещать $( ) вокруг всего! Это - синтаксис для замены команды, которая является только одним способом использовать вывод команды. Каналы и замена процесса и здесь-строки являются другими, и у них всех есть другой синтаксис, естественно. Вы не должны анализировать имена файлов так или иначе, если Вы действительно не знаете то, что Вы делаете. –  jw013 16.10.2012, 23:41
  • 2
    Спасибо это работало, будет читать больше о Process Substitution. –  RanRag 16.10.2012, 23:44
  • 3
    @jw013: Я - новичок удара. В будущем сохранит Ваше предложение в моем уме. –  RanRag 16.10.2012, 23:45

Обратите внимание, что нет ничего мешающего именам файлов содержать символы новой строки. Канонический способ выполнить команду для каждого файла, найденного находкой.

find . -type f -exec cmd {} \;

И если Вы хотите вещи, сделанные в ударе:

find . -type f -exec bash -c '
  for file do
    something with "$file"
  done' bash {} +

Кроме того, канонический способ назвать команду "чтения" в сценариях (если Вы не хотите, чтобы это сделало дополнительную обработку на входе):

IFS= read -r var

-r должен остановиться read от обработки символов обратной косой черты особенно (как символ ESC для разделителей и новой строки), И IFS = для установки списка разделителей к пустой строке для read (иначе, если бы какой-либо пробельный символ был в том списке, то они были бы разделены с начала и конца входа).

Используя циклы в оболочках обычно плохая идея (не, как вещи сделаны в оболочках, где Вы заставляете несколько инструментов работать коллективно и одновременно к задаче вместо того, чтобы выполнить один или несколько инструментов сотни времен в последовательности).

13
27.01.2020, 19:34

Нет необходимости в подстановке команд, если вы хотите использовать канал. readпо умолчанию читается из stdin, так что вы просто подключаетесь к нему:

find. -type f -print0 |
while read -r -d '' line
do
    echo "$line"
done

или в одну строку

find. -type f -print0 | while read -r -d '' line; do echo "$line"; done

Использование -print0и -d ''является защитной мерой от возможного символа новой строки в именах файлов, который по умолчанию указывает конец строки наread(это можно изменить с помощью-d). Используемый выше ''фактически является нулевым байтом в bash(, эквивалентном$'\0').

Другой уже упомянутый подход заключается в использовании опции find's -exec. Скорее всего, это будет лучший вариант производительности -мудрый (не забудьте использовать вариант -exec cmd {} +, чтобы он не разветвлял процесс для каждой обрабатываемой строки ). Но это действительно зависит от того, что вы делаете внутри цикла whileи сколько данных вы обрабатываете. Разница может быть незначительной или приемлемой для вашего случая.

12
11.04.2020, 16:57

Теги

Похожие вопросы