Як відобразити кількість рядків, що виводяться командою в режимі реального часу?


15

Я використовую svn exportяк частину сценарію упаковки для свого додатка, і схоже, що ця команда, як і багато інших, не має жодної панелі прогресу.

На даний момент у мене є два варіанти:

  • використовуючи його без опцій, і спостерігайте, як він друкує тисячі рядків
  • використовувати --quiet, а не шити нічого, поки це не завершиться.

Чи є спосіб хоча б показати кількість рядків, що виводяться командою, в режимі реального часу? Як от:

Exporting SVN directory ... 1234 files

І бачите цей 1234 приріст кількості в режимі реального часу ? Я можу уявити, як виводить результат на команду, яка б робила саме це, але до якої?

Відповіді:


16
yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

Або помістіть розділений в коробку розділ у сценарій оболонки. Зауважте, що це працює лише в тому випадку, якщо ваша оболонка насправді підтримує попередній оператор, наприклад, bash або ksh93 або zsh. Інакше вам доведеться збільшувати, $Iа потім друкувати (як у I=$((I+1));printf...). Крім того, якщо printfце не вбудований з вашою оболонкою (це вбудований з поточним bash), ви можете використовувати echo -neабо print -nзамість цього для кращої продуктивності. Ви просто хочете придушити новий рядок і інтерпретувати \ n як символ втечі.


О, я ніколи не змушу себе вчитися кераміки з усіма її потворними =відмінностями та химерностями. :) Чому б вони не замінили його синтаксизованою мовою ...
Борис Бурков

Гей, я знаю, що! Ви можете додати символ повернення каретки до кожного нового друкованого рядка, і він не заповнить екран, він просто замінить попередній рядок.
Борис Бурков

Ось чому printfзакінчується а \r. А що станеться, якщо ви зробите echo -ne "$I\r"або print -n "$I\r". :) Я використовував printf, однак, тому що він за замовчуванням не друкує новий рядок наприкінці, тому \rпросто рухається назад до початку. На жаль, не всі ехопрограми підтримують аргумент -eабо -nаргумент.
dannysauer

1
Це також працює з версією pdksh, яку OpenBSD використовує для / bin / sh.
kurtm

1
+1, хоч і є абсолютно правильним, слід змінити readна read -r(оскільки в іншому випадку зворотна косою рисою в кінці рядка зіпсується з підрахунком). До речі, за допомогою трохи роботи це можна адаптувати так, щоб відображати останній рядок виводу, який може бути корисним для деяких команд.
ruakh

7

Це приблизна ідея, але ви можете скористатися pvкомандою, щоб підрахувати кількість рядків під час їх проходження та відобразити їх на екрані. pvсеред його безлічі комутаторів є -lперемикач, який рахує кожну лінію під час її проходження.

Приклад

Тут я використовую цикл час, щоб імітувати деякі файли з вашого виводу SVN.

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

Він буде продовжувати перезапис вихідного рядка таким чином:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

Я не знав про пв. Ураг для навчальних матеріалів!
dannysauer

@dannysauer - pv варто витратити деякий час на навчання, воно дозволяє перевіряти та показувати все, що проходить через трубу.
slm

Я встановив його після того, як прочитав коментар і пограв з ним. Вісімнадцять років користуються Linux, і завжди є нові речі для відкриття. :)
dannysauer

0

Ви можете запустити свою команду у фоновому режимі як завдання та перенаправити її stdout (і stderr необов'язково) на логфайл: command > logfile &де &позначається завдання (якщо і stderr, скажіть &>замість >).

Тоді ви можете скористатися утилітою wordcount, щоб підрахувати кількість рядків у вашому лог-файлі wc -l.

Щоб показати зміну стану в одній динамічно мінливій лінії, ви можете використовувати щось на кшталт while true; do echo -en '\r'; wc -l logfile; sleep 1; done, але я не можу змусити bash намалювати \rповернення каретки, щоб знищити вміст попереднього рядка.

Дивіться це запитання, це майже копія: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash


1
Але він хоче відображати в режимі реального часу, який постійно збільшується, а це не те, що робить Wc.
kurtm

@kurtm е, що він хоче набагато більше - це не забивати його екран результатами printf/print/echo, запропонованими Danny. :) Звичайно, він міг би скористатися less, але я гадаю, він може дозволити собі говорити wc -l logfileщоразу, коли стає нетерплячим. Я думаю, що грати з ncursesекраном чи очищати його від екрану є непосильним.
Борис Бурков

Ну так. Він не хоче, щоб його затопило, але він хоче знати прогрес, інакше він може просто використовувати - тихо.
kurtm

@kurtm див. оновлення: чи можете ви допомогти налагодити мою echo -e 'r'команду? Він повинен стерти раніше надрукований вміст рядка, щоб він динамічно змінювався, але я не можу його змусити це робити :(
Борис Бурков

Ви також хочете додати n варіант для відлуння, що пригнічує зворотний новий рядок.
kurtm
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.