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 KiB; але він рекомендує, щоб цей буфер динамічно розподілявся та розширювався за необхідності, що і 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 -
має те саме питання.