You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Shell识别上一次输出并优化Python脚本重复打印?

问题解答

一、让Shell识别上一次输出内容的方法

  • 捕获命令输出到变量:如果需要保存上一条命令的输出内容,直接将命令结果赋值给变量:
    last_output=$(ls -l)
    # 之后可以使用$last_output调用内容
    echo "$last_output"
    
  • 结合历史命令获取输出:如果要复用上一条命令的输出,可通过历史命令结合命令替换实现:
    # 先执行目标命令
    echo "hello world"
    # 获取上一条命令的输出
    last_output=$(!!)
    
  • 持久化保存输出到文件:用tee命令同时输出到终端和文件,后续可读取文件内容:
    ls -l | tee last_output.txt
    # 读取保存的输出
    cat last_output.txt
    
  • 获取命令退出状态:若只需判断上一条命令是否执行成功,用$?变量,0表示执行成功,非0表示失败:
    ls non_exist_file
    echo $?  # 输出非0值,代表命令执行失败
    

二、修改Python脚本避免重复输出

原脚本循环中会重复打印相同结果,我们通过添加变量跟踪上一次输出类型,仅当当前类型与上一次不同时才打印。修改后的代码如下:

import yfinance as yf
import mplfinance as mpf
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd

# Dates to get stock data
start_date = "2010-07-01"
end_date = "2023-06-19"

# Fetch Tesla stock data
tesla_data = yf.download("TSLA", start=start_date, end=end_date)
tesla_weekly_data = tesla_data.resample("W").agg(
    {"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}
).dropna()

# Get the latest closing price
latest_price = tesla_weekly_data['Close'][-1]

# Calculate the EMA with different lengths
ema_lengths = [8, 13, 21, 55]
ema_colors = ['blue', 'green', 'yellow', 'red']
ema_lines = []
for length, color in zip(ema_lengths, ema_colors):
    ema_line = tesla_weekly_data['Close'].ewm(span=length, adjust=False).mean()
    ema_lines.append(ema_line)

# Create additional plot
apds = []
close_price = tesla_weekly_data['Close']
apds.append(mpf.make_addplot(close_price, color='cyan', width=2))

# Add EMA lines
for ema_line, color in zip(ema_lines, ema_colors):
    apds.append(mpf.make_addplot(ema_line, color=color))

# Plot the candlestick chart with EMA lines
fig, axes = mpf.plot(tesla_weekly_data,
                     type='candle',
                     addplot=apds,
                     style='yahoo',
                     title='Tesla Stock Prices',
                     ylabel='Price',
                     volume=True,
                     ylabel_lower='Volume',
                     volume_panel=1,
                     figsize=(16, 8),
                     returnfig=True,
                     warn_too_much_data=2800,
                     )

# Move the y-axis labels to the left side
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_left()

# Adjust the position of the y-axis label for price
axes[0].yaxis.set_label_coords(-0.08, 0.5)

# Adjust the position of the y-axis label for volume
axes[1].yaxis.set_label_coords(-0.08, 0.5)

# Set y-axis label for price and volume
axes[0].set_ylabel('Price', rotation=0, labelpad=20)
axes[1].set_ylabel('Volume', rotation=0, labelpad=20)

# Make the legend box
handles = axes[0].get_legend_handles_labels()[0]
red_patch = mpatches.Patch(color='red')
green_patch = mpatches.Patch(color='green')
cyan_patch = mpatches.Patch(color='cyan')
handles = handles[:2] + [red_patch, green_patch, cyan_patch]
labels = ["Price Up", "Price Down", "Closing Price"]
axes[0].legend(handles=handles, labels=labels)

# Add a box to display the current price
latest_price_text = f"Current Price: ${latest_price:.2f}"
box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes,
             fontsize=12, verticalalignment='top', bbox=box_props)

# Function to create hover annotations
def hover_annotations(data):
    annot_visible = False
    annot = axes[0].text(0, 0, '', visible=False, ha='left', va='top')

    def onmove(event):
        nonlocal annot_visible
        nonlocal annot

        if event.inaxes == axes[0]:
            index = int(event.xdata)
            if index >= len(data.index):
                index = -1
            elif index < 0:
                index = 0
            values = data.iloc[index]
            mytext = (f"{values.name.date().strftime('%m/%d/%Y'):}\n"+
                      f"O: {values['Open']:.2f}\n"+
                      f"H: {values['High']:.2f}\n"+
                      f"L: {values['Low']:.2f}\n"+
                      f"C: {values['Close']:.2f}\n"+
                      f"V: {values['Volume']:.0f}"
                     )

            annot_visible = True
        else:
            mytext = ''
            annot_visible = False

        annot.set_position((event.xdata, event.ydata))
        annot.set_text(mytext)
        annot.set_visible(annot_visible)
        fig.canvas.draw_idle()

    fig.canvas.mpl_connect('motion_notify_event', onmove)

    return annot

# Attach hover annotations to the plot
annotations = hover_annotations(tesla_weekly_data)

# Get the lines' data points
lines = axes[0].get_lines()

linecyan = None  # Variable to store the leftmost point of Line 1
lineblue = None  # Variable to store the leftmost point of Line 2
linegreen = None  # Variable to store the leftmost point of Line 3
lineyellow = None  # Variable to store the leftmost point of Line 4
linered = None  # Variable to store the leftmost point of Line 5

# Get the x-values from the DataFrame index
x = tesla_weekly_data.index

# 记录上一次的输出类型,初始化为None
last_output_type = None

# Iterate over x-values
for x_value in x:
    x_index = tesla_weekly_data.index.get_loc(x_value)
    for line in lines:
        if line.get_color() == 'cyan':
            y_data = line.get_ydata()
            linecyan = y_data[x_index]
            
        if line.get_color() == 'blue':
            y_data = line.get_ydata()
            lineblue = y_data[x_index]
            
        if line.get_color() == 'green':
            y_data = line.get_ydata()
            linegreen = y_data[x_index]
            
        if line.get_color() == 'yellow':
            y_data = line.get_ydata()
            lineyellow = y_data[x_index]
            
        if line.get_color() == 'red':
            y_data = line.get_ydata()
            linered = y_data[x_index]

    # 判断当前输出类型并生成对应文本
    current_output_type = None
    current_output_text = ""
    
    if linered > linegreen:
        if linered > lineyellow:
            if linered > lineblue:
                current_output_type = "Over"
                current_output_text = f"Line Red is Over all 3 other lines at x = {x_value}"
            else:
                current_output_type = "Neither"
                current_output_text = f"Line Red is not over or under all 3 other lines at x = {x_value}"
        else:
            current_output_type = "Neither"
            current_output_text = f"Line Red is not over or under all 3 other lines at x = {x_value}"
    elif linered < linegreen:
        if linered < lineyellow:
            if linered < lineblue:
                current_output_type = "Under"
                current_output_text = f"Line Red is Under all 3 other lines at x = {x_value}"
            else:
                current_output_type = "Neither"
                current_output_text = f"Line Red is not over or under all 3 other lines at x = {x_value}"
        else:
            current_output_type = "Neither"
            current_output_text = f"Line Red is not over or under all 3 other lines at x = {x_value}"
    else:
        current_output_type = "Problem"
        current_output_text = "Problem!"

    # 仅当当前类型与上一次不同时才打印
    if current_output_type != last_output_type:
        print(current_output_text)
        print("---------------------\n")
        # 更新上一次的输出类型
        last_output_type = current_output_type

# Show the plot
plt.show()

修改说明:

  1. 添加last_output_type变量,用于跟踪上一次的输出类型(Over/Under/Neither/Problem)。
  2. 将原打印逻辑拆分为类型判断和文本生成两部分,明确当前输出的分类。
  3. 增加条件判断:只有当当前输出类型与上一次不同时,才打印内容和分隔线,并更新last_output_type的值。

内容的提问来源于stack exchange,提问作者Damian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:47:03