如何将 bash 函数用于日期值

How can I use bash function for date values

我有这样的日志文件 (xferlog):

Mon Jan  5 09:52:58 2015 1 10.0.0.1 0 /home/DATA1/123.sqlLdr b _ i r DATA1 ftp 0 * c

我需要 ftp 所有图案的转移日期(最后一次转移),如下所示:

201501050952 ( yearmonthdayhourminute )

我可以这样做:

xfer1=$(tac "/var/log/xferlog" | awk -v pattern="DATA1" ' ~ pattern {print; exit}')

day1=${xfer1:8:2}
month1=${xfer1:4:3}
year1=${xfer1:20:4}
hour1=${xfer1:11:2}
minute1=${xfer1:14:2}

# For converting Jan, Feb... --> 01, 02

if [ "$month1" == "Jan" ];then
month1=01
fi
if [ "$month1" == "Feb" ];then
month1=02
...

# For converting month - 1,2,3 --> 01, 02, 03

day1s=$day1
if [ "$day1" == " 1" ];then
day1s=01
fi
if [ "$day1" == " 2" ];then
day1s=02
fi
...

echo "DATA1: $year1$month1$day1s$hour1$minute1"
...

这是可行的,但我需要对其他模式执行相同的过程。像这样:

xfer1=$(tac "/var/log/xferlog" | awk -v pattern="DATA1" ' ~ pattern {print; exit}')
xfer2=$(tac "/var/log/xferlog" | awk -v pattern="LIN5" ' ~ pattern {print; exit}')
...

如何使用转换日期格式的函数并使用所有格式?以及如何在函数中使用变量?我可以做不同的变量名和转换(day1 day2 day3 ...),但它很长而且不常见。

您可以使用 Python,我希望它是不言自明的。我对其进行了编辑,使其成为一个 "Bash" 片段,其中嵌入了 Python 脚本。

tac "/var/log/xferlog" | python -c "
import datetime
import fileinput

for line in fileinput.input():
    path = line.split()[8]
    user = path.split('/')[2]
    if user in ('DATA1', 'LIN5'):
        dt = datetime.datetime.strptime(line[:24], '%a %b %d %H:%M:%S %Y')
        print dt.strftime('%Y%m%d%H%M')
"

循环你已有的模式是一件很容易的事情。

for pat in DATA1 LIN5; do
    xfer=$(tac /var/log/xferlog |
        awk -v pattern="$pat" ' ~ pattern { print; exit }')
    : massive ugly date processing here
    echo "$PAT: $year1$month1$day1s$hour1$minute1"
done

您也可以轻松地将日期处理因素纳入 Awk 脚本。

for pat in DATA1 LIN5; do
    tac /var/log/xferlog |
    awk -v pattern="$pat" 'BEGIN {
        m="Jan:Feb:Mar:Apr:May:Jun:Sep:Oct:Nov:Dec";
        n=split(m, mm, /:/); for (i=1; i<=n; i++) month[mm[i]]=i; }
         ~ pattern { printf("%s: %04i%02i%02i%02i%02i\n", pattern,
            substr([=11=], 21, 4), month[substr([=11=], 5, 3)], 0+substr([=11=], 9, 2),
            substr([=11=], 12,2), substr([=11=], 15, 2)); exit }'
done

为了提高处理效率,您也可以将模式考虑到 Awk 脚本中。不过,跟踪模式列表并在找到所有模式后退出是一个小问题。

tac /var/log/xferlog |
awk 'BEGIN { pat["DATA"]=1; pat["LIN5"]=1; 
    m="Jan:Feb:Mar:Apr:May:Jun:Sep:Oct:Nov:Dec";
    n=split(m, mm, /:/); for (i=1; i<=n; i++) month[mm[i]]=i; }
    { for (k in pat) if ( ~ pat[k]) { printf("%s: %04i%02i%02i%02i%02i\n", pattern,
        substr([=12=], 21, 4), month[substr([=12=], 5, 3)], 0+substr([=12=], 9, 2),
        substr([=12=], 12,2), substr([=12=], 15, 2)); delete pat[k]; break }
    length(pat) == 0 { exit }'