2014-02-10 29 views
0

我有這種命令,我發現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

我應該鏈接這到meta.stackoverflow.com「XY問題」 ......爲什麼你不能簡單地調用'日期+「%Y%M% d%H「(它直接給出'YYYYMMDDHH'輸出,請參閱http://pubs.opengroup.org/onlinepubs/009604599/utilities/date.html瞭解格式規範的可能性)? –

回答

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在Solaris nawk內部被初始化,所以第一個調用確實返回一天中的時間,即從該時期開始經過的秒數。
  • 如果您想要一種嚴格便攜的方式,您需要在獲取其返回值之前運行第一個srand()調用,但在Solaris下不需要此方法。
  • 這是便攜式(即POSIX),不像使用truss
+0

srand是一個隨機數發生器。我不明白這是如何讓我30天前的日期。 – taylordurden

+0

你混淆了'rand'和'srand'。看到我更新的答案。 – jlliagre

0

編輯:最初我已經在Linux上創建了一個很好的響應,但在Solaris上卻沒有。現在這個時間要長得多,原始答案在下面。

要純粹在shell中執行此操作,只能使用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標誌完成的。例如

$ 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 
+0

不幸的是,Solaris沒有date -d。 '日期:非法選項 - d' – taylordurden

+0

對不起。我正在使用Linux服務器來測試。我看到Solaris不提供''+%s''格式,所以多次失敗。 – Gabe

0

如果你有Solaris 11中,答案很簡單,因爲它是kshksh93。該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 
+0

Dang,我們正在使用Solaris 10 – taylordurden