截断带有前缀的Python脚本的“包装”长字符串输出,在保留空间的每个转储的底部附加新行

问题描述 投票:0回答:2

我正在尝试为控制台输出添加前缀,同时将长字符串输出截断为最多 60 个字符。 (防止长线溢出并破坏前缀)

怎么会...

esc=$(printf '\033')
sudo apt upgrade 2>&1 >&1 | sed -e "s/.\{0,60\}/${esc}[35m║      &\n/g"

...是否在保留空间的每个转储下方附加一个新的(无前缀)行?我怎样才能阻止这种行为,或者至少为其添加一个前缀?

输出:

║      

║      WARNING: apt does not have a stable CLI interface. Use with 
║      caution in scripts.

║      

║      Reading package lists...

║      Building dependency tree...

║      Reading state information...

║      Calculating upgrade...

║      0 upgraded, 0 newly installed, 0 to remove and 0 not upgrade
║      d.

║

[编辑1]

根据 chorobaEd Morton 提供的解决方案,两者都非常适合

sudo apt upgrade
“尽管“解决方案 2”似乎首先将所有内容打印到缓冲区,然后一次性转储所有信息,而不是流式传输像
sed
一样缓冲到控制台似乎正在做。”
.

解决方案1:

sudo apt upgrade 2>&1 >&1 | sed -e 's/^\(.\{0,60\}\).*/'"$esc"'[35m║      \1/'

解决方案2:

sudo apt upgrade 2>&1 >&1 | fold -s -w60 | sed "s/^/${esc}[35m║    /"

我提出问题的时候,用了

apt upgrade
作为一个简单的例子,认为“输出”就是“输出”。然而,我实际上正在尝试运行我编写的用于安装 Django 网站的 python 脚本,并且我在这些解决方案中遇到了更多问题。

当使用任一解决方案执行此 python 脚本时,根本没有任何输出,直到最后报告

./install.sh: line 561: Collecting: command not found

我以为在 BASH 控制台中只有

STDOUT
STDERR
,并且我已将这两个通道重定向到一个输出通道,但我猜测 python 脚本的输出既不是这些,还是其他东西?

我正在执行的运行脚本的命令如下:

$($VENV_DIR/bin/python3 install.py) 2>&1 >&1 |
+ 这里提供的解决方案。

*注意:从技术上讲,我是在 VirtualENV 内部执行它的,它是在我的 BASH 脚本中使用以下命令激活的:

    echo -e "${PURPLE}║"
    echo -e "${PURPLE}║    ${NC}Activating VENV..."

    source $VENV_DIR/bin/activate
    
    echo -e "${PURPLE}║"
    echo -e "${PURPLE}║      VENV: " $VIRTUAL_ENV

我不确定这是否与此有关,只是想提一下。


为了更好地理解,这是我想要实现的最终结果。标准典型控制台输出的边框、框架、样式和整体美化。几乎就像 shell 中的 GUI,如果这有意义的话。我知道这是不必要的,但我当然很欣赏结果。

python bash sed trailing-newline
2个回答
1
投票

您需要将整行替换为前 60 个字符。

sed -e 's/^\(.\{0,60\}\).*/'"$esc"'[35m║      \1/'
#          ~~         ~~^^                    ~~
#           1          1 2                     3
  • 1
    记住前 60 个字符,
  • 2
    与其余部分匹配,
  • 3
    输出记住的部分。

1
投票

您的替换字符串明确表示在每 0 到 60 个字符后添加一个换行符,这就是 sed 正在做的事情,然后它像往常一样在所有输出的末尾打印一个终止换行符,这就是导致空行的原因出现。使用较小的输入和较小的范围更容易看到:

$ echo '1234' | sed 's/.\{0,2\}/<&>\n/g'
<12>
<34>

$
$ echo '12345' | sed 's/.\{0,2\}/<&>\n/g'
<12>
<34>
<5>

$

解决问题的方法有多种,但您似乎试图换行(又称折叠)线而不是截断它们,所以请尝试以下方法:

fold -s -w60 | sed "s/^/${esc}[35m║    /"

这里使用的是我认为你的原始输出

sudo apt upgrade 2>&1 >&1
可能看起来像的输入:

$ cat file
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists...
Building dependency tree...
Reading state information...
Calculating upgrade...
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

$ cat file | fmt -s -w60 | sed "s/^/${esc}[35m║    /"
║    WARNING: apt does not have a stable CLI interface. Use
║    with caution in scripts.
║
║    Reading package lists...
║    Building dependency tree...
║    Reading state information...
║    Calculating upgrade...
║    0 upgraded, 0 newly installed, 0 to remove and 0 not
║    upgraded.

请注意,

fold
在空白处分割输入(如果可以的话),而你的 sed 命令会在单词中间截断行,这会产生更混乱的输出。

© www.soinside.com 2019 - 2024. All rights reserved.