cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS
Проблема с переводом этого к чему-то, что использует то, tailчто tailнужно прочитать весь файл, чтобы найти его конец. Чтобы использовать это в своем конвейере, вам нужно
- Предоставьте полное содержание документа
tail.
- Обеспечить его снова в
cat.
- В этой последовательности.
Сложность заключается не в том, чтобы дублировать содержимое документа ( teeделает это), а в том, чтобы получить результат tailдо того, как будет выведен остальной документ, без использования промежуточного временного файла.
Использование sed(или awk, как это делает John1024 ) избавляет от двойного анализа данных и проблемы упорядочения, сохраняя данные в памяти.
sedРешение , которое я предлагаю , чтобы
1{h;d;}, сохраните первую строку в пространстве удержания, как есть, и перейдите к следующей строке.
H, добавьте каждую строку к пробелу со встроенной новой строкой.
${G;p;}, добавьте пробел к последней строке со встроенной новой строкой и напечатайте полученные данные.
Это довольно буквальный перевод решения John1024 в sed, с оговоркой, что стандарт POSIX гарантирует только то, что пространство удержания составляет по крайней мере 8192 байта (8 КиБ; но он рекомендует, чтобы этот буфер динамически выделялся и расширялся по мере необходимости, что оба GNU sedи BSD sedделает).
Если вы позволите себе использовать именованный канал:
mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe
Это используется teeдля отправки данных вниз mypipeи в то же время cat. catУтилита первого чтения вывода tail(который считывает с mypipe, который teeпишет в), а затем добавить копию документа , приходящий непосредственно из tee.
Однако в этом есть серьезный недостаток, заключающийся в том, что если документ слишком большой (больше, чем размер буфера канала), teeзапись mypipeи catблокирование будут выполняться в ожидании опустошения (без имени) канала. Он не будет опустошен, пока не catпрочитан из него. catне будет читать с него, пока tailне закончил. И tailне закончил бы, пока teeне закончил. Это классическая тупиковая ситуация.
Вариация
tee >( tail -n 1 >mypipe ) | cat mypipe -
имеет ту же проблему.