当将终端的进度显示重定向到文件时,会显示为多行

编程语言 2026-07-09

我写了一个进度显示程序,用来在终端上显示。通过 |& tee a.txt 将进度输出重定向到一个文件时,每次有进度更新,输出就会在多行显示。如何在重定向的输出文件中阻止这种行为?我希望重定向的输出文件与终端输出保持一致。

main.cpp

#include <chrono>
#include <iostream>
#include <thread>

void write_progress(const double progress, const std::chrono::seconds& elapsed_time, const std::string& display_text, const char fill = '#') {
    static constexpr size_t bar_width = 100;

    // No need to write once progress is 100%
    if (progress > 100.0) {
        return;
    }

    // Hide cursor
    std::cout << "\033[?25l";

    // Move cursor to the first position on the same line and flush
    std::cout << "\r" << std::flush;

    std::cout << display_text;

    // Write progress percentage
    std::cout << ": " << progress << "%";

    // Start of the bar
    std::cout << " [ ";

    const auto completed = static_cast<size_t>(progress * bar_width / 100.0);
    std::cout << std::string(completed, fill);
    std::cout << std::string(bar_width - completed, ' ');

    // End of the bar
    std::cout << " ] ";

    std::cout << "\tET: " << elapsed_time.count() << "s";

    // Show cursor
    std::cout << "\033[?25h";
}

void progress(const std::string& status_text) {
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    for (int i = 0; i <= 100; i+= 10) {
        std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
        write_progress(static_cast<double>(i), std::chrono::duration_cast<std::chrono::seconds>(end - begin), status_text);
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << std::endl;
}

int main() {
    progress("Processing Status");
}

命令

./a.out |& tee a.txt

a.txt

[?25l
Processing Status: 0% [                                                                                                      ]  ET: 0s[?25h[?25l
Processing Status: 10% [ ##########                                                                                           ]     ET: 1s[?25h[?25l
Processing Status: 20% [ ####################                                                                                 ]     ET: 2s[?25h[?25l
Processing Status: 30% [ ##############################                                                                       ]     ET: 3s[?25h[?25l
Processing Status: 40% [ ########################################                                                             ]     ET: 4s[?25h[?25l
Processing Status: 50% [ ##################################################                                                   ]     ET: 5s[?25h[?25l
Processing Status: 60% [ ############################################################                                         ]     ET: 6s[?25h[?25l
Processing Status: 70% [ ######################################################################                               ]     ET: 7s[?25h[?25l
Processing Status: 80% [ ################################################################################                     ]     ET: 8s[?25h[?25l
Processing Status: 90% [ ##########################################################################################           ]     ET: 9s[?25h[?25l
Processing Status: 100% [ #################################################################################################### ]    ET: 10s[?25h

期望的a.txt内容

Processing Status: 100% [ #################################################################################################### ] T: 0s  ET: 10s

解决方案

我想你可能在找 ansifilter 这个工具。只需要执行 ansifilter a.txt > b.txt,你就会得到“渲染后的”文件内容。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章