Bash编码返回具有特定字符串的文件名

Bash编码返回具有特定字符串的文件名,bash,Bash,我在bash中的脚本旨在完成这项工作: 从文件获取开始和停止时间,文件\ a。时间范围通常为3-24小时 基于从文件\u A获取的[开始\u时间,停止\u时间]的时间窗口, 我需要在总共10k个日志文件中找到特定的文件,并且随着实验运行的增加,每个日志文件记录了大约30分钟。也就是说,我必须在10k日志文件中找到6-50个日志文件 确认正确的日志文件后,我需要打印出有趣的数据 第一步和第三步都可以,我已经做了。 现在,我陷入了第二步,特别是在两个地方: a。由于日志文件名为time,如何根据文件

我在bash中的脚本旨在完成这项工作:

从文件获取开始和停止时间,文件\ a。时间范围通常为3-24小时

基于从文件\u A获取的[开始\u时间,停止\u时间]的时间窗口, 我需要在总共10k个日志文件中找到特定的文件,并且随着实验运行的增加,每个日志文件记录了大约30分钟。也就是说,我必须在10k日志文件中找到6-50个日志文件

确认正确的日志文件后,我需要打印出有趣的数据

第一步和第三步都可以,我已经做了。 现在,我陷入了第二步,特别是在两个地方:

a。由于日志文件名为time,如何根据文件名高效地选择合适的文件。每个名为log_201305280650的日志文件表示2013/05/28/06:50。也就是说,根据从文件_A获取的时间,我需要根据相应的日志文件的名称确认它们,这是时间的提示

b。选择文件后,从时间在时间窗口内的文件中读取项目,如温度、压力等。因为每个文件记录30分钟,这意味着该文件中的某些条目不能满足时间窗口的要求

比如说,

从步骤1开始,我的时间窗口设置为[201305280638,201305290308]

从步骤2,我知道日志文件log_201305280650包含201305280638的开始时间。所以我需要读取201305280638以下条目的所有温度和压力

    the log files name is log_201305280650 (= 2013 / May 28 / 06 :50)

    Time                      temperature  pressure ...
    201305280628                100,         120  ...
    201305280629                100,         120  ...

   ...              ...     ...

    201305280638                101,         121  ...
    201305280639                99,          122  ...

     ...             ...     ... 

    201305280649                101,         119  ...
    201305280650                102,         118  ...
我的假脚本如下

get time_start from /path/file_A
get time_stop  from /path/file_A
for file in /path_to_log_files/*
do
case "$file" in
*)        
     If [[log file name within time window of (time_start, time_stop)]]; then
     loop over this file to get the entry whose time is just within (time_start, time_stop)
     read out temperature and pressure etc.
fi
esac
done

使用bash做得很好。Perl或python更容易,它们都有日期/时间模块

我花了一段时间做了通常的日期切片,结果很糟糕,所以我作弊并使用了文件时间戳。Bash有一些有限的时间戳检查,这就使用了它。好的,它有一些文件IO,但这些是空文件,这是什么鬼东西

lower=201305280638
upper=201305290308
filename=log_201305280638
filedate=${filename:4}

if (( filedate == upper )) || (( filedate == lower ))
then
    echo "$filename within range"
else
    # range files
    touch -t $lower lower.$$
    touch -t $upper upper.$$

    # benchmark file
    touch -t $filedate file.$$

    if [[ file.$$ -nt $upper ]]
    then
        echo "$filename is too young"

    elif [[ file.$$ -ot $lower ]]
    then
        echo "$filename is too old"
    else
        echo "$filename is just right"
    fi

    rm lower.$$ upper.$$ file.$$
fi
-nt比

-ot比


因此,在开始时检查是否相等。您可以对第二期发行的文件中的时间戳进行类似的检查。但是老实说,你不能使用perl或python吗?

也许类似的东西对你有用?我使用$start和$end作为文件_A.I中的开始和结束时间

 eval cat log_{$start..$end} 2> /dev/null | sort -k1 | sed -n "/$start/,/$end/p"
这假定日志文件的格式为

time temperature pressure ...

如果没有标题或其他此类文本

,使用awk和date命令的+%s选项代替文字日期和时间可能会更容易。此选项将日期/时间从1970年1月1日起转换为秒。得到的数字很容易处理。毕竟,这只是一个数字。作为一个例子,我制作了一个小的bash脚本。首先,模拟:

#!/bin/bash

#simulation: date and time
start_dt="2013-09-22 00:00:00"
end_dt="2013-09-22 00:00:00"
start_secs=$(date -d "start_dt" +"%s")
end_secs=$(date -d "end_dt" +"%s")
#simulation: set up table (time in secs, temperature, pressure per minute)
> logfile
for ((i=$start_secs;i<$end_secs;i=i+60)); do
    echo $i $[90+$[RANDOM %20]] $[80+$[RANDOM %30]] >> logfile
done
下面是获取用户范围并将其打印出来的实际脚本:

echo "Enter start of range:"
read -p "Date (YYYY-MM-DD): "sdate
read -p "Time (HH:MM:SS)  : "stime
echo "Enter end of range:"
read -p "Date (YYYY-MM-DD): "edate
read -p "Time (HH:MM:SS)  : "etime
#convert to secs
rstart=$(date -d "$sdate $stime" +"%s")
rend=$(date -d "$edate $etime" +"%s")
#print it to screen
awk -v rstart=$rstart -v rend=$rend '{if($1 >= rstart && $1 <= rend)print $0}' logfile

awk命令非常适合这种情况。它速度快,可以处理大文件。我希望这能给你一些想法。

你可能想多读一读,把它整理一下。根本不清楚你的实际问题是什么。为什么你的案例陈述有两次?TMI。如果您提供SSCCE,您将更有可能获得帮助。事实上,这还不够清楚。不过我还是尽力想说清楚。嗨,伙计们:非常感谢你们的关注!我对我的帖子做了很多修改。希望它看起来比以前清晰多了。最好的你好,@cdarke,非常感谢您的回复和第一时间!老实说,由于我在bash中的级别有限,我没有资格评估您的代码。然而,根据这个链接。大多数人不鼓励使用$$-我不是说你的代码不好-我真的无法判断。但是,很明显,您实际上建议我强烈使用python或perl。我会认真考虑这一点,并试图找出一个最好的解决方案,我在Python有一个很小的背景。无论如何,再次感谢你@user2740039:好的,但是使用$$使代码更简单,我个人认为在这种情况下它是合理的。你不必使用它。关键是你的时间戳格式对于触摸来说是完全正确的,如果是巧合的话,浪费这种巧合似乎是一种耻辱。