Почему вы не читаете строки с "for" в bash?

Я читал, что использование "for" не очень хороший способ читать строки в bash. Многие люди говорят, что в лучшем случае это неуклюже и неэффективно, а во многих случаях терпит неудачу.

Я хотел бы знать, как лучше всего читать строки в bash. Благодарю.

Например:

$ for i in $(<afile); do echo "$i"; done

1 ответ

Решение

Вы говорите о for line in $(cat file); do и подобные конструкции. Это:

  • Неэффективно, потому что bash должен порождать подоболочку и выполнять cat, читать catвыводит - весь файл - в память, анализирует его (что является самой медленной частью), только затем перебирает все данные
  • Ненадежный, потому что bash выполняет разбиение слов в данных - он разделяется не только на символы новой строки, но и на что-либо в $IFS (пробелы, табуляции...)

(Если вы используете $(<...) вместо $(cat ...), вы экономите две миллисекунды в Linux, но все остальные недостатки остаются.)

Гораздо лучшим вариантом является использование readвwhileцикл:

while read -r line; do
    echo "Input: $line"
done < myfile.txt

Или из программы:

cat file1 file2 file3 |
while read -r line; do
    echo "Input: $line"
done

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

Если вы пытаетесь работать с выводом find, вы должны использовать тот же шаблон:

find . -name "foo" -type f -print0 | while read -r -d '' file; do
    echo "File: $file"
done

Смотрите также:

Другие вопросы по тегам