cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS
Le problème avec la traduction de ceci en quelque chose qui utilise tailest qu'il tailfaut lire le fichier entier pour en trouver la fin. Pour utiliser cela dans votre pipeline, vous devez
- Fournissez le contenu complet du document à
tail.
- Fournir à nouveau à
cat.
- Dans cet ordre.
L'astuce n'est pas de dupliquer le contenu du document ( teefait cela) mais de faire en sorte que la sortie de tailse produise avant la sortie du reste du document, sans utiliser de fichier temporaire intermédiaire.
L'utilisation sed(ou awk, comme le fait John1024 ) supprime la double analyse des données et le problème de commande en stockant les données en mémoire.
La sedsolution que je propose est de
1{h;d;}, stockez la première ligne dans l'espace d'attente, telle quelle, et passez à la ligne suivante.
H, ajoutez-vous une ligne à l'espace d'attente avec une nouvelle ligne incorporée.
${G;p;}, ajoutez l'espace d'attente à la dernière ligne avec une nouvelle ligne incorporée et imprimez les données résultantes.
Il s'agit d'une traduction assez littérale de la solution de John1024 sed, avec la mise en garde que la norme POSIX garantit uniquement que l'espace de blocage est d'au moins 8192 octets (8 Ko), mais il recommande que ce tampon soit alloué dynamiquement et étendu selon les besoins, ce que GNU tous les deux sedet BSD sedfait).
Si vous vous autorisez à utiliser un canal nommé:
mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe
Cela permet teed'envoyer les données vers le bas mypipeet en même temps vers cat. L' catutilitaire lira d'abord la sortie de tail(qui lit mypipe, qui teeécrit), puis ajoutera la copie du document provenant directement de tee.
Il y a cependant un sérieux défaut, dans le cas où si le document est trop volumineux (plus grand que la taille de la mémoire tampon du tube), il teeécrit mypipeet catse bloquerait en attendant que le tube (sans nom) se vide. Il ne serait pas vidé avant d'être catlu. catne le lirait pas avant d' tailavoir terminé. Et tailne finirait pas avant d' teeavoir fini. Il s'agit d'une situation de blocage classique.
La variation
tee >( tail -n 1 >mypipe ) | cat mypipe -
a le même problème.