Pour le contexte, j'essaie de créer un script shell qui simplifie la sortie de la console en temps réel de ffmpeg, en affichant uniquement l'image courante en cours d'encodage. Mon objectif final est d'utiliser cette information dans une sorte d'indicateur de progression pour le traitement par lots.Suppression en temps réel du retour chariot dans le shell
Pour ceux qui ne connaissent pas la sortie de ffmpeg, il sort des informations vidéo codées pour stdout et consoler les informations vers stderr. En outre, lorsqu'il affiche les informations de codage, il utilise les retours chariot pour empêcher l'écran de la console de se remplir. Cela rend impossible d'utiliser simplement grep et awk pour capturer les informations de ligne et de trame appropriées.
La première chose que j'ai essayé est de remplacer les retours chariot en utilisant tr:
$ ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | tr '\r' '\n'
Cela fonctionne en ce qu'il affiche une sortie en temps réel à la console. Cependant, si je redirige cette information vers grep ou awk ou toute autre chose, la sortie de tr est tamponnée et n'est plus en temps réel. Par exemple: $ ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | tr '\r' '\n'>log.txt
résulte dans un fichier qui est immédiatement rempli avec certaines informations, puis 5-10 secondes plus tard, plus de lignes sont déposées dans le fichier journal. Au début, je pensais que sed serait bon pour cela: $ # ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | sed 's/\\r/\\n/'
, mais il arrive à la ligne avec tous les retours chariot et attend jusqu'à ce que le traitement est terminé avant de tenter de faire quoi que ce soit. Je suppose que c'est parce que sed travaille ligne par ligne et a besoin que toute la ligne soit complétée avant de faire quoi que ce soit d'autre, et ensuite elle ne remplace pas les retours chariot de toute façon. J'ai essayé différentes regex pour le retour chariot et la nouvelle ligne, et je n'ai pas encore trouvé de solution qui remplace le retour chariot. J'utilise OSX 10.6.8, donc j'utilise BSD sed, ce qui pourrait expliquer cela.
J'ai également essayé d'écrire l'information dans un fichier journal et d'utiliser tail -f
pour le relire, mais je rencontre toujours le problème du remplacement des retours chariot en temps réel.
J'ai vu qu'il existe des solutions pour cela en python et perl, cependant, je suis réticent à suivre cette voie immédiatement. Premièrement, je ne connais pas python ou perl. Deuxièmement, j'ai une application de traitement par lots complètement fonctionnelle que je devrais soit porter, soit comprendre comment intégrer python/perl. Probablement pas dur, mais pas ce que je veux entrer à moins que je doive absolument le faire. Donc, je cherche une solution shell, de préférence bash, mais n'importe quel OSX serait bien.
Et si ce que je veux n'est tout simplement pas faisable, eh bien je suppose que je traverserai ce pont quand j'arriverai là.
Merci beaucoup! Votre première commande fonctionne parfaitement bien que j'utilise 'awk' depuis que je suis sur OSX. Cela me sauve tellement de maux de tête! – Seth
Une chose à ajouter à cette excellente réponse: vérifiez votre documentation awk/gawk/mawk installée pour savoir comment interpréter RS. Dans ma boîte OSX locale, awk avait un OU implicite pour le séparateur d'enregistrement (soit retour chariot, soit retour à la ligne). Sur mon serveur Ubuntu, gawk 4.0.1 interprète RS comme une expression régulière s'il a plus d'un caractère. Donc, j'ai dû utiliser 'RS = '\ r | \ n'' pour obtenir le même comportement que j'ai vu sur OSX. – ajmicek