UNIX: Get the date of N days ago

本文介绍了一种实用脚本,用于清理指定天数之前的旧日志文件。该脚本能够根据输入参数确定目标日期,并从指定的日志文件夹中删除早于该日期的所有日志文件。
Here is a real practice: House keep log files which have been out of date for N days.


if [ $# -ne 2 ];then
echo "Usage: $0 [develop|uat|prod] [ N days ago ]"
exit -1
fi
ENV=$1
N_DAYS_AGO=$2

function getDays {
_thisMon=$1
_thisYear=`date +%Y`
_div4=`expr $_thisYear \% 4`
_div100=`expr $_thisYear \% 100`
_div400=`expr $_thisYear \% 400`

if [ $_thisMon -eq 2 ];then
if [ $_div4 -eq 0 -a $_div100 -ne 0 -a $_div400 -ne 0 ];then
echo 28
else
echo 29
fi
elif [ $_thisMon -eq 2 -O $_thisMon -eq 4 -o $_thisMon -eq 6 -o $_thisMon -eq 9 -o $_thisMon -eq 11 ];then
echo 30
else
echo 31
fi
}

logFolder="/script/logs"
TMP_FILE=.house_keep_log.tmp

#`date +%m`

THIS_YEAR=`date +%Y`
THIS_MONTH=`date +%m`
THIS_DAY=`date +%d`

DUE_YEAR=$THIS_YEAR
DUE_MONTH=$THIS_MONTH
DUE_DAY=$THIS_DAY

if [ $THIS_DAY -gt $N_DAYS_AGO ];then
DUE_DAY=`expr $THIS_DAY - $N_DAYS_AGO`
else
_TMP=`expr $N_DAYS_AGO - $THIS_DAY`
LAST_MONTH=`expr $THIS_MONTH - 1`

if [ $LAST_MONTH -eq 0 ];then
LAST_MONTH=12
DUE_YEAR=`expr $THIS_YEAR -1`
fi

LAST_MONTH_DAYS=`getDays $LAST_MONTH`

if [ $_TMP -gt $LAST_MONTH_DAYS ];then
echo "Can NOT accept $N_DAYS_AGO as 'N days ago' parameter!"
exit -1
fi
DUE_MONTH=$LAST_MONTH
DUE_DAY=`expr $LAST_MONTH_DAYS - $_TMP`

if [ $DUE_MONTH -lt 10 ];then
DUE_MONTH="0"${DUE_MONTH}
fi
fi
echo "The date of today is :$THIS_YEAR-$THIS_MONTH-$THIS_DAY"
echo "The date of $N_DAYS_AGO days ago is :$DUE_YEAR-$DUE_MONTH-$DUE_DAY"

cd $logFolder
touch -t "${DUE_YEAR}${DUE_MONTH}${DUE_DAY}0000" $TMP_FILE
for log in *.log
do
ls -l $log
if [ $log -ot $TMP_FILE ];then
#log is before FILE_B
echo "Delete $log"
rm -f $log
fi
done

rm -f $TMP_FILE
import struct import pandas as pd from datetime import datetime, timedelta def parse_dy2(file_path): # 目标日期范围(今天及近7天) today = datetime(2025, 10, 4) target_start = today - timedelta(days=7) # 从分析结果获得的关键参数 record_length = 24 # 最可能的记录长度 price_positions = [8, 12, 16, 20] # 基于价格位置分析的推测 possible_time_positions = [0, 4] # 可能的时间字段位置 with open(file_path, 'rb') as f: file_content = f.read() total_size = len(file_content) print(f"文件大小: {total_size}字节") # 计算记录数量 record_count = total_size // record_length print(f"使用记录长度: {record_length}字节, 预计记录数: {record_count}") # 尝试不同的时间字段位置 for time_pos in possible_time_positions: data = [] for i in range(min(5000, record_count)): start = i * record_length end = start + record_length if end > total_size: break chunk = file_content[start:end] try: # 解析时间字段 time_val = struct.unpack('<I', chunk[time_pos:time_pos+4])[0] date = None # 尝试1: 作为Unix时间戳(秒) if 1730000000 <= time_val <= 1740000000: # 2025年前后的时间戳范围 date = datetime.fromtimestamp(time_val) # 尝试2: 作为自2025-10-01起的分钟数 else: base = datetime(2025, 10, 1, 9, 0, 0) date = base + timedelta(minutes=time_val) # 验证日期合理性 if not (target_start <= date <= today): continue # 解析价格(使用分析发现的位置和单位) prices = [] units = [1, 1, 1, 100] # 基于分析结果的单位推测 for p in range(4): pos = price_positions[p] if pos + 4 > len(chunk): break val = struct.unpack('<I', chunk[pos:pos+4])[0] price = val / units[p] prices.append(price) if len(prices) != 4: continue open_p, high_p, low_p, close_p = prices # 验证价格合理性 if (100 <= open_p <= 100000 and 100 <= high_p <= 100000 and 100 <= low_p <= 100000 and 100 <= close_p <= 100000 and high_p >= low_p): # 解析成交量(最后4字节) if len(chunk) >= 24: volume = struct.unpack('<I', chunk[20:24])[0] if 0 < volume <= 1e7: data.append([date, open_p, high_p, low_p, close_p, volume]) except Exception as e: continue # 检查是否解析到足够的有效记录 if len(data) > 10: df = pd.DataFrame(data, columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume']) df = df.sort_values('Date').drop_duplicates('Date') print(f"\n成功解析 {len(df)} 条有效记录! (时间字段位置: {time_pos})") return df print("\n未找到有效数据格式") return None # 使用示例 file_path = r'C:\镁质材料交易中心行情分析端\DATA\DriverRTA\MIN.DY2' result_df = parse_dy2(file_path) if result_df is not None: print("\n解析结果(前10条):") print(result_df.head(10)) if len(result_df) > 1: print("\n时间间隔统计:") print(result_df['Date'].diff().dt.total_seconds().describe())
10-05
帮忙逐句解读和汇总解读作用 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 增强型源数据库管理器 扩展源数据库管理器,提供更多高级功能和优化的数据同步方法。 """ import logging import datetime from typing import List, Dict, Any, Optional, Tuple, Union import pymysql from pymysql.cursors import DictCursor from Colion.model.database.source_db_manager import SourceDatabaseManager from Colion.model.database.db_manager import DatabaseManager class EnhancedSourceDatabaseManager(SourceDatabaseManager): """ 增强型源数据库管理器类 扩展源数据库管理器,提供更多高级功能和优化的数据同步方法。 """ def __init__(self, host: str, port: int, user: str, password: str, database: str, charset: str = 'utf8mb4'): """ 初始化增强型源数据库管理器 Args: host: 数据库主机 port: 数据库端口 user: 数据库用户名 password: 数据库密码 database: 数据库名 charset: 数据库字符集,默认为utf8mb4 """ super().__init__(host, port, user, password, database, charset) self.logger = logging.getLogger('Colion.EnhancedSourceDatabaseManager') self.logger.info("增强型源数据库管理器初始化完成") def ensure_indexes(self, local_db: DatabaseManager): """ 确保本地数据库中的索引存在 Args: local_db: 本地数据库管理器 """ try: # 为query表创建索引 if local_db.table_exists('query'): # 检查日期列是否存在 columns = local_db.query("PRAGMA table_info(query)") column_names = [col['name'] for col in columns] if '日期' in column_names: local_db.execute("CREATE INDEX IF NOT EXISTS idx_query_date ON query(日期)") self.logger.info("已确保query表的日期索引存在") # 为work_order_list表创建索引 if local_db.table_exists('work_order_list'): columns = local_db.query("PRAGMA table_info(work_order_list)") column_names = [col['name'] for col in columns] if 'createDate' in column_names: local_db.execute("CREATE INDEX IF NOT EXISTS idx_work_order_createDate ON work_order_list(createDate)") if 'id' in column_names: local_db.execute("CREATE INDEX IF NOT EXISTS idx_work_order_id ON work_order_list(id)") self.logger.info("已确保work_order_list表的索引存在") # 为part_category表创建索引(检查列是否存在) if local_db.table_exists('part_category'): columns = local_db.query("PRAGMA table_info(part_category)") column_names = [col['name'] for col in columns] if 'part_code' in column_names: local_db.execute("CREATE INDEX IF NOT EXISTS idx_part_category_code ON part_category(part_code)") self.logger.info("已确保part_category表的索引存在") else: self.logger.info("part_category表中不存在part_code列,跳过索引创建") # 为part_info表创建索引(检查列是否存在) if local_db.table_exists('part_info'): columns = local_db.query("PRAGMA table_info(part_info)") column_names = [col['name'] for col in columns] if 'part_code' in column_names: local_db.execute("CREATE INDEX IF NOT EXISTS idx_part_info_code ON part_info(part_code)") self.logger.info("已确保part_info表的索引存在") else: self.logger.info("part_info表中不存在part_code列,跳过索引创建") # 为view_sop_progress表创建索引(如果需要的话) if local_db.table_exists('view_sop_progress'): self.logger.info("已确保view_sop_progress表存在") except Exception as e: self.logger.error(f"确保索引存在失败: {str(e)}", exc_info=True) def sync_query_max_date(self, local_db: DatabaseManager) -> Dict[str, Any]: """ 同步query表中日期字段最大值对应的行 Args: local_db: 本地数据库管理器 Returns: 同步结果 """ try: self.logger.info("开始同步query表中日期字段最大值对应的行") # 确保连接有效 if not self.conn: self.connect() # 获取源表结构 source_columns = self.get_table_columns('query') if not source_columns: self.logger.error("获取源表结构失败") return {'status': '失败', 'message': '获取源表结构失败', 'row_count': 0} # 检查本地表是否存在,如果不存在则创建 if not local_db.table_exists('query'): self.logger.info("本地表不存在,创建表") local_db.create_table('query', source_columns) else: # 检查是否需要添加新列 local_columns = local_db.get_table_info('query') local_column_names = [col['name'] for col in local_columns] new_columns = [col for col in source_columns if col['name'] not in local_column_names] if new_columns: self.logger.info(f"添加 {len(new_columns)} 个新列到本地表") local_db.add_columns('query', new_columns) # 获取日期字段的最大值 max_date_result = self.query("SELECT MAX(日期) as max_date FROM query") if not max_date_result or not max_date_result[0]['max_date']: self.logger.warning("源表中没有日期数据") return {'status': '失败', 'message': '源表中没有日期数据', 'row_count': 0} max_date = max_date_result[0]['max_date'] self.logger.info(f"获取到日期字段的最大值: {max_date}") # 获取最大日期对应的行 query = f"SELECT * FROM query WHERE 日期 = '{max_date}'" source_data = self.query(query) if not source_data: self.logger.warning(f"源表中没有日期为 {max_date} 的数据") return {'status': '成功', 'message': f'源表中没有日期为 {max_date} 的数据', 'row_count': 0} row_count = len(source_data) self.logger.info(f"从源数据库获取到 {row_count} 条记录") # 清空本地表 local_db.execute("DELETE FROM query") self.logger.info("已清空本地query表") # 插入数据到本地表 placeholders = ', '.join(['?' for _ in source_data[0].keys()]) columns = ', '.join(source_data[0].keys()) insert_sql = f"INSERT INTO query ({columns}) VALUES ({placeholders})" for row in source_data: local_db.execute(insert_sql, list(row.values())) self.logger.info(f"成功同步 {row_count} 条记录到本地数据库") return { 'status': '成功', 'message': f'成功同步 {row_count} 条记录', 'row_count': row_count } except Exception as e: self.logger.error(f"同步query表失败: {str(e)}", exc_info=True) return { 'status': '失败', 'message': f'同步失败: {str(e)}', 'row_count': 0 } def sync_work_order_list_incremental(self, local_db: DatabaseManager) -> Dict[str, Any]: """ 全表同步work_order_list表 使用分批处理方式,每批处理10000条记录,避免内存溢出 在同步前清空本地数据库中的表 Args: local_db: 本地数据库管理器 Returns: 同步结果 """ try: self.logger.info("开始全表同步work_order_list表") # 确保连接有效 if not self.conn: self.connect() # 获取源表结构 source_columns = self.get_table_columns('work_order_list') if not source_columns: self.logger.error("获取源表结构失败") return {'status': '失败', 'message': '获取源表结构失败', 'row_count': 0} # 检查本地表是否存在,如果不存在则创建 if not local_db.table_exists('work_order_list'): self.logger.info("本地表不存在,创建表") local_db.create_table('work_order_list', source_columns) else: # 检查是否需要添加新列 local_columns = local_db.get_table_info('work_order_list') local_column_names = [col['name'] for col in local_columns] new_columns = [col for col in source_columns if col['name'] not in local_column_names] if new_columns: self.logger.info(f"添加 {len(new_columns)} 个新列到本地表") local_db.add_columns('work_order_list', new_columns) # 清空本地表 local_db.execute("DELETE FROM work_order_list") self.logger.info("已清空本地work_order_list表") # 执行分批同步 return self._do_sync_work_order_list_full(local_db) except Exception as e: self.logger.error(f"同步work_order_list表失败: {str(e)}", exc_info=True) return { 'status': '失败', 'message': f'同步失败: {str(e)}', 'row_count': 0 } def _do_sync_work_order_list_full(self, local_db: DatabaseManager) -> Dict[str, Any]: """ 执行work_order_list表的同步,只同步前一个月的数据 使用分批处理方式,每批处理10000条记录 Args: local_db: 本地数据库管理器 Returns: 同步结果 """ try: # 计算一个月前的日期 one_month_ago = (datetime.datetime.now() - datetime.timedelta(days=30)).strftime('%Y-%m-%d') # 获取一个月内的记录数 count_result = self.query(f"SELECT COUNT(*) as total FROM work_order_list WHERE createDate >= '{one_month_ago}'") total_count = count_result[0]['total'] if total_count == 0: self.logger.warning("源表中没有一个月内的数据") return {'status': '成功', 'message': '源表中没有一个月内的数据', 'row_count': 0} self.logger.info(f"源表中一个月内共有 {total_count} 条记录") # 设置批处理大小 batch_size = 10000 # 计算总批次数 total_batches = (total_count + batch_size - 1) // batch_size # 记录总同步行数 total_synced = 0 # 分批处理 for batch in range(total_batches): offset = batch * batch_size # 获取当前批次的数据,只获取一个月内的数据 query = f"SELECT * FROM work_order_list WHERE createDate >= '{one_month_ago}' LIMIT {batch_size} OFFSET {offset}" batch_data = self.query(query) if not batch_data: self.logger.warning(f"批次 {batch + 1}/{total_batches} 没有数据") continue batch_count = len(batch_data) self.logger.info(f"批次 {batch + 1}/{total_batches}: 获取到 {batch_count} 条记录") # 插入数据到本地表 if batch_count > 0: # 获取列名 columns = list(batch_data[0].keys()) placeholders = ', '.join(['?' for _ in columns]) columns_str = ', '.join(columns) # 构建插入语句 insert_sql = f"INSERT INTO work_order_list ({columns_str}) VALUES ({placeholders})" # 批量插入 for row in batch_data: local_db.execute(insert_sql, list(row.values())) total_synced += batch_count self.logger.info(f"批次 {batch + 1}/{total_batches}: 已同步 {batch_count} 条记录,总计: {total_synced}/{total_count}") self.logger.info(f"work_order_list表全表同步完成,共同步 {total_synced} 条记录") return { 'status': '成功', 'message': f'全表同步完成,共同步 {total_synced} 条记录', 'row_count': total_synced } except Exception as e: self.logger.error(f"执行work_order_list表全表同步失败: {str(e)}", exc_info=True) return { 'status': '失败', 'message': f'全表同步失败: {str(e)}', 'row_count': 0 } def sync_view_sop_progress(self, local_db: DatabaseManager) -> Dict[str, Any]: """ 同步view_sop_progress表 一次性同步完成,每次写入前先清空表 Args: local_db: 本地数据库管理器 Returns: 同步结果 """ try: self.logger.info("开始同步view_sop_progress表") # 确保连接有效 if not self.conn: self.connect() # 获取源表结构 source_columns = self.get_table_columns('view_sop_progress') if not source_columns: self.logger.error("获取源表结构失败") return {'status': '失败', 'message': '获取源表结构失败', 'row_count': 0} # 检查本地表是否存在,如果不存在则创建 if not local_db.table_exists('view_sop_progress'): self.logger.info("本地表不存在,创建表") local_db.create_table('view_sop_progress', source_columns) else: # 检查是否需要添加新列 local_columns = local_db.get_table_info('view_sop_progress') local_column_names = [col['name'] for col in local_columns] new_columns = [col for col in source_columns if col['name'] not in local_column_names] if new_columns: self.logger.info(f"添加 {len(new_columns)} 个新列到本地表") local_db.add_columns('view_sop_progress', new_columns) # 获取源表数据 query = "SELECT * FROM view_sop_progress" source_data = self.query(query) if not source_data: self.logger.warning("源表中没有数据") return {'status': '成功', 'message': '源表中没有数据', 'row_count': 0} row_count = len(source_data) self.logger.info(f"从源数据库获取到 {row_count} 条记录") # 清空本地表 local_db.execute("DELETE FROM view_sop_progress") self.logger.info("已清空本地view_sop_progress表") # 插入数据到本地表 if row_count > 0: # 获取列名 columns = list(source_data[0].keys()) placeholders = ', '.join(['?' for _ in columns]) columns_str = ', '.join(columns) # 构建插入语句 insert_sql = f"INSERT INTO view_sop_progress ({columns_str}) VALUES ({placeholders})" # 批量插入 for row in source_data: # 转换数据类型,处理 Decimal 类型 converted_values = [] for value in row.values(): if hasattr(value, '__class__') and value.__class__.__name__ == 'Decimal': # 将 Decimal 转换为 float converted_values.append(float(value)) else: converted_values.append(value) local_db.execute(insert_sql, converted_values) self.logger.info(f"成功同步 {row_count} 条记录到本地数据库") return { 'status': '成功', 'message': f'成功同步 {row_count} 条记录', 'row_count': row_count } except Exception as e: self.logger.error(f"同步view_sop_progress表失败: {str(e)}", exc_info=True) return { 'status': '失败', 'message': f'同步失败: {str(e)}', 'row_count': 0 }
07-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值