【问题标题】:getting last three lines of python output assigned to 3 variables in bash将最后三行 python 输出分配给 bash 中的 3 个变量
【发布时间】:2022-02-13 20:03:03
【问题描述】:

我有一个输出一长串文件的 python 脚本。

脚本是从 bash 运行的,最后我需要将最后三个文件分别分配给一个特定的变量。

我能够将输出捕获到一个 bash 变量中,但是当我尝试将其通过管道传递给“tail”命令时,它似乎只有一行?

我尝试了一些我见过的技巧,但似乎无法弄清楚如何在单个行的基础上使用输出。

似乎任何python输出都会被解释为一行?


echo "TESTING sample multi-line python output"
OUTPUT=$(python -c "for i in range(5): print(i)")

# check output
echo "$OUTPUT"

variable3=$(echo $OUTPUT | tail -1)

echo "VARIABLE CAPTURED"
echo $variable3

这是我得到的:

但我实际上需要将变量 1 作为从末尾开始的第 3 行,将变量 2 作为从末尾开始的第 2 行,将变量 3 作为从末尾开始的第一行

所以在上面的例子中,最终想要的结果是:

variable1 = 2
variable2 = 3
variable3 = 4

为了将这些变量传递给脚本的下一阶段...

【问题讨论】:

  • 你需要引用"$OUTPUT",否则在IFS(空格,包括新行)上被分割,echo打印每个参数,用空格分隔。 python -c ... | tail -n3.

标签: python bash


【解决方案1】:

您必须正确引用,这会将4 分配给variable3

variable3="$(echo "$OUTPUT" | tail -1)"
echo "$variable3"

同样,获取variable2

variable2="$(echo "$OUTPUT" | tail -2 | head -1)"

还有variable1:

variable1="$(echo "$OUTPUT" | tail -3 | head -1)"

总结起来,你的脚本应该是:

#!/usr/bin/env bash

echo "TESTING sample multi-line python output"
OUTPUT="$(python -c "for i in range(5): print(i)")"

# check output
echo "$OUTPUT"

variable3="$(echo "$OUTPUT" | tail -1)"
variable2="$(echo "$OUTPUT" | tail -2 | head -1)"
variable1="$(echo "$OUTPUT" | tail -3 | head -1)"

echo variable1: "$variable1"
echo variable2: "$variable2"
echo variable3: "$variable3"

【讨论】:

    【解决方案2】:

    所以我无法解释为什么会这样,但似乎 pythons print 将行分隔为 '\n'tail 将行分隔为 \n\r。所以我通过改变一些行来完成这项工作

    echo "TESTING sample multi-line python output"
    OUTPUT=$(python -c "for i in range(5): print(str(i) + '\n\r', end='')")
    
    # check output
    echo "$OUTPUT"
    
    variable3=$(echo $OUTPUT | tail -1)
    
    echo "VARIABLE CAPTURED"
    echo $variable3
    

    这将导致

    TESTING sample multi-line python output
    0
    1
    2
    3
    4
    
    VARIABLE CAPTURED
    4 
    

    【讨论】:

    • 那么variable2variable1呢?
    • @ArkadiuszDrabczyk,例如他可以split it to array。使用 $variable1,2,3... 看起来像纯硬编码
    • 但是你会如何在你的代码中使用这个?
    【解决方案3】:

    一个选项可以是 tail -3 并将最后几行读入一个数组:

    #!/bin/bash
    
    echo "TESTING sample multi-line python output"
    readarray -t arr <<< "$(python -c "for i in range(5): print(i)" | tail -3)"
    
    echo "VARIABLE CAPTURED"
    echo "${arr[0]}"
    echo "${arr[1]}"
    echo "${arr[2]}"
    
    echo "VIA LOOP"
    for var in "${arr[@]}"; do
        echo "$var"
    done
    

    输出

    TESTING sample multi-line python output
    VARIABLE CAPTURED
    2
    3
    4
    VIA LOOP
    2
    3
    4
    

    如果你真的需要在提取最后三行之前保存完整的输出:

    OUTPUT="$(python -c "for i in range(5): print(i)")"
    readarray -t arr <<< "$(echo "$OUTPUT" | tail -3)"
    

    【讨论】:

      【解决方案4】:

      当您不需要当前环境时,可以使用set
      当您想使用变量名称variable# 时,您需要复制它们。

      set -- $( python -c "for i in range(5): print(i)"| tail -3)
      variable1="$1"; variable2="$2"; variable3="$3"
      # In my environment I can check the results with
      set | grep "^variable.="
      

      另一种选择是将它们读入变量中:

      read -rd "\n" variable1 variable2 variable3 < <(
        python -c "for i in range(5): print(i)"| tail -3
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-01
        • 2012-02-02
        • 2012-07-16
        • 2012-06-18
        • 1970-01-01
        • 2018-02-26
        • 1970-01-01
        • 2016-07-14
        相关资源
        最近更新 更多