我有这个命令,我发现here:
/usr/bin/truss /usr/bin/date 2>&1 |
nawk -F= '/^time\(\)/ {gsub(/" "/,"",$2);printf "0t%d=Y\n", $2-30*86400}' |
adb
打印2014 Jan 11 09:48:54
。有谁知道如何将输出重新格式化为YYYYMMDDHH?
我必须在Solaris上使用ksh。我不能使用perl。
答案 0 :(得分:0)
几条评论:
第一个命令:
/usr/bin/truss /usr/bin/date 2>&1 |
nawk -F= '/^time\(\)/ {gsub(/" "/,"",$2);printf "0t%d=Y\n", $2-30*86400}'
可能会被更轻松,更简单的
取代 nawk 'BEGIN {printf("0t%d=Y\n",srand()-30*86400)}'`
adb
是否理解0txx=Y
语法,mdb
肯定是这样。那就是说,这里应该符合你的需要:
nawk 'BEGIN {printf("0t%d=Y\n",srand()-30*86400)}' | mdb | nawk '
function m2m(m)
{
if(m=="Jan")return 1
if(m=="Feb")return 2
if(m=="Mar")return 3
if(m=="Apr")return 4
if(m=="May")return 5
if(m=="Jun")return 6
if(m=="Jul")return 7
if(m=="Aug")return 8
if(m=="Sep")return 9
if(m=="Oct")return 10
if(m=="Nov")return 11
if(m=="Dec")return 12
}
{
y=$1
m=$2
d=$3
split($4,t,":")
h=t[1]
min=t[2]
printf("%s%02d%02d%02d%02d\n",y,m2m(m),d,h,min)
}'
注意:
srand
(不要与rand
混淆)在调用时返回上一个种子。srand
使用“当天时间”作为种子。srand
内部初始化nawk
时,第一个srand()
调用会返回当天的时间,即自纪元以来经过的秒数。truss
不同,这是便携式的(即POSIX)。答案 1 :(得分:0)
编辑:最初我已经形成了一个在Linux上运行良好的响应,但在Solaris上却没有。现在这个时间要长得多,原来的答案如下。
要在Solaris上完全执行此操作,只能使用date
函数。的种类。您还必须创建一些shell函数来帮助减去给定日期之后的天数。
使用以下功能,您可以执行以下操作以获得所需的结果:
$ mydate="$(date '+%Y%m%d')"
$ hours="$(date '+%H')"
$ echo "$(date_subtract "${mydate}" 30)${hours}" | adb
或类似的......
在Solaris上,date
命令仅提供公历日期。对于这个问题,这很难处理,所以我创建了一个shell函数gregorian_to_julian
,它可以将'YYYYMMDD'格式的日期转换为'YYYYDDD'的Julian日期。
function gregorian_to_julian {
# "Expecting input as YYYYMMDD."
typeset gregorian_date=$1
typeset _year=$(echo "${gregorian_date}" | cut -c1-4)
typeset _month=$(echo "${gregorian_date}" | cut -c5-6)
typeset _day=$(echo "${gregorian_date}" | cut -c7-8)
typeset days
days[01]=31
days[02]=$(( days[01] + 28 ))
if (( _year % 4 == 0 )) && (( _year % 100 != 0 )) || (( _year % 400 == 0 )); then
days[02]=$(( days[01] + 29 ))
fi
days[03]=$(( 31 + days[02] ))
days[04]=$(( 30 + days[03] ))
days[05]=$(( 31 + days[04] ))
days[06]=$(( 30 + days[05] ))
days[07]=$(( 31 + days[06] ))
days[08]=$(( 31 + days[07] ))
days[09]=$(( 30 + days[08] ))
days[10]=$(( 31 + days[09] ))
days[11]=$(( 30 + days[10] ))
typeset julian_date=0
case "${_month}" in
"01") julian_date=$_day ;;
"02") julian_date=$(( days[01] + _day )) ;;
"03") julian_date=$(( days[02] + _day )) ;;
"04") julian_date=$(( days[03] + _day )) ;;
"05") julian_date=$(( days[04] + _day )) ;;
"06") julian_date=$(( days[05] + _day )) ;;
"07") julian_date=$(( days[06] + _day )) ;;
"08") julian_date=$(( days[07] + _day )) ;;
"09") julian_date=$(( days[08] + _day )) ;;
"10") julian_date=$(( days[09] + _day )) ;;
"11") julian_date=$(( days[10] + _day )) ;;
"12") julian_date=$(( days[11] + _day )) ;;
esac
julian_date="${_year}${julian_date}"
echo "${julian_date}"
}
了解OP希望将日期格式化为格里高利日期,我创建了第二个函数julian_to_gregorian
,它将Julian日期转换回来。
function julian_to_gregorian {
# "Expecting input as YYYYDDD."
#set -x
typeset julian_date=$1
typeset _year="$(echo "${julian_date}" | cut -c1-4)"
typeset _month=""
typeset julian_day="$(echo "${julian_date}" | cut -c5-7)"
typeset -RZ2 _day=0
typeset days
days[01]=31
days[02]=$(( days[01] + 28 ))
if (( _year % 4 == 0 )) && (( _year % 100 != 0 )) || (( _year % 400 == 0 )); then
days[02]=$(( days[01] + 29 ))
fi
days[03]=$(( 31 + days[02] ))
days[04]=$(( 30 + days[03] ))
days[05]=$(( 31 + days[04] ))
days[06]=$(( 30 + days[05] ))
days[07]=$(( 31 + days[06] ))
days[08]=$(( 31 + days[07] ))
days[09]=$(( 30 + days[08] ))
days[10]=$(( 31 + days[09] ))
days[11]=$(( 30 + days[10] ))
if (( days[11] < julian_day )); then _month="12"; _day=$(( julian_day - days[11] ));
elif (( days[10] < julian_day )); then _month="11"; _day=$(( julian_day - days[10] ));
elif (( days[09] < julian_day )); then _month="10"; _day=$(( julian_day - days[09] ));
elif (( days[08] < julian_day )); then _month="09"; _day=$(( julian_day - days[08] ));
elif (( days[07] < julian_day )); then _month="08"; _day=$(( julian_day - days[07] ));
elif (( days[06] < julian_day )); then _month="07"; _day=$(( julian_day - days[06] ));
elif (( days[05] < julian_day )); then _month="06"; _day=$(( julian_day - days[05] ));
elif (( days[04] < julian_day )); then _month="05"; _day=$(( julian_day - days[04] ));
elif (( days[03] < julian_day )); then _month="04"; _day=$(( julian_day - days[03] ));
elif (( days[02] < julian_day )); then _month="03"; _day=$(( julian_day - days[02] ));
elif (( days[01] < julian_day )); then _month="02"; _day=$(( julian_day - days[01] ));
else
_month="01"; _day=${julian_day};
fi
echo "${_year}${_month}${_day}"
}
第三个函数date_subtract
采用格里高利日期,将其转换为朱利安,进行日期数学运算,并转换回格里高利。
function date_subtract {
typeset julian_from_date=$(gregorian_to_julian "$1")
typeset number_of_days=$2
typeset julian_year=$(echo "${julian_from_date}" | cut -c1-4)
typeset julian_days=$(echo "${julian_from_date}" | cut -c5-7)
typeset leap_year="FALSE"
if (( julian_days - number_of_days > 0 )); then
(( julian_days -= number_of_days ))
else
(( julian_year -= 1 ))
if (( julian_year % 4 == 0 )) && (( julian_year % 100 != 0 )) || (( julian_year % 400 == 0 )); then
leap_year="TRUE"
fi
if [[ "${leap_year}" == "TRUE" ]]; then
(( julian_days = julian_days + 366 - number_of_days ))
else
(( julian_days = julian_days + 365 - number_of_days ))
fi
fi
typeset gregorian_date=$(julian_to_gregorian "${julian_year}${julian_days}")
echo "${gregorian_date}"
}
编辑:以下适用于Linux。而且更简单。
如果您需要格式为YYMMDDHH
的日期,那么这很简单,就像@FrankH一样。在他的评论中指出:
date +"%Y%m%d%H"
更棘手的部分是计算30天前的日期,这似乎是你的意图。 date
命令可以占用纪元以来的秒数并将其转换为日期字符串。这是通过-d
标志完成的。 e.g。
$ date -d @123456789
Thu Nov 29 15:33:09 CST 1973
所以,如果你需要三十天前的日期,我们可以采取这个原则,并做一些数学计算,以获得所需的价值。
请注意date '+%s'
给出了自纪元以来的秒数。
$ date -d @$(( $(date '+%s') - $((60 * 60 * 24 * 30 )) )) '+%Y%m%d%H'
2014011211
如果您需要将该日期字符串传递给adb
,那么您可以使用$(...)包围该命令。
echo $( date -d @$(( $(date '+%s') - $((60 * 60 * 24 * 30 )) )) '+%Y%m%d%H' ) | adb
答案 2 :(得分:0)
如果您有Solaris 11,答案很简单,因为ksh
为ksh93
。 Solaris 11 ksh man page包含有关printf
的信息:
A %(date-format)T format can be use to treat an argument as a date/time string
and to format the date/time according to the date-format as defined for the
date(1) command.
ksh
手册页中未指定允许的日期/时间字符串格式,但在AST tm(3) man page中(有些)提及。种类繁多。特别是,这将做你想要的:
$ printf "%(%Y%m%d%H)T\n"
2014021118
$ printf "%(%Y%m%d%H)T\n" now
2014021118
$ printf "%(%Y%m%d%H)T\n" "30 days ago"
2014011218