Shell-Script
Unix Shell 程序來檢測它是哪個半月。日期(dom)-le 16
最終目標是設置一個變數,它將是 YYYYMMDD,其中 DD 是兩個變數之一(01 或 16)
我正在嘗試完成將變數創建為兩個值之一。
這是我到目前為止所擁有的,但它不起作用:
DYA=date +%d DYB=IF [["$DYA" -ge 16]]; then 16 else 01 fi YR=2020 MO=03 FD="$YR$MO$DY" ECHO "$FD"
使用
bash
4.2 或更高版本:#!/bin/bash printf -v day '%(%e)T' -1 if [[ $day -lt 16 ]]; then # 1st half of the month day=01 else # 2nd half of the month day=16 fi printf '%(%Y%m)T%s\n' -1 "$day"
第一個
printf
將當月的目前日期作為十進制數字列印到變數day
中。這些if
語句將其限制為01
或16
取決於其值。最後
printf
列印目前年份和月份,然後將01
or16
字元串添加到其末尾。呼叫的
-1
參數printf
使%(...)T
格式字元串使用目前時間作為格式化的時間戳(如果您使用的是bash
4.3 或更高版本,則第一次呼叫並不嚴格需要,因為它是隱式的)。更緊湊的版本
bash
:#!/bin/bash printf -v day '%(%e)T' -1 printf '%(%Y%m)T%.2d\n' -1 "$(( (day < 16) ? 1 : 16 ))"
在這裡,我使用通用三元運算符
?:
在算術擴展中執行測試。1
如果$day
小於 16,則計算字元串,如果大於 16,16
則計算結果。然後將算術擴展的結果格式化為填充零的整數並插入到目前年份和月份之後。關於您的程式碼:
- 請注意,兩者和
[[ ... ]]
周圍都需要空格(好吧,可以在沒有空格的情況下立即出現,因為它是命令終止符)。[[``]]``;
- 如果要將
date
或任何命令的輸出放入變數中,請使用命令替換:day=$( date +%e )
。if
如果要輸出一個值(它不輸出),這對於您的語句來說是正確的。- Unix 命令區分大小寫,因此
ECHO
應該是echo
.- 時間格式輸出一個介於和之間的
%d
零填充整數。請注意,在算術上下文(語句)中使用這樣的值會將值解釋為八進制值,並且會為and產生錯誤(這些是無效的八進制數)。這就是為什麼我改用在和之間獲取非零填充的整數的原因。01``31``if``01``07``08``09``%e``1``31
關於最後一點:我也可以使用
printf -v day '%(%d)T' -1
01
在和之間獲得零填充值31
,但是我需要使用if [[ 10#$day -ge 16 ]]; then
強制 shell 將字元串解釋為十進制整數而不是八進制整數。
作為
/bin/sh
腳本(也適用bash
於 4.2 之前的版本,例如bash
macOS 上的預設 shell):#!/bin/sh day=$( date +%e ) if [ "$day" -lt 16 ]; then # 1st half of the month day=01 else # 2nd half of the month day=16 fi date +"%Y%m$day"
標準
sh
shell 沒有 的%(...)T
格式字元串bash
,所以我們不得不用date
它來做日期字元串的格式化。它還[ ... ]
用於測試而不是[[ ... ]]
(並且變數需要在其中被雙引號括起來)。更緊湊的版本
/bin/sh
:#!/bin/sh day=$( date +%e ) printf '%s%.2d\n' "$(date +%Y%m)" "$(( (day < 16) ? 1 : 16 ))"
這個更緊湊的版本來自緊湊的
bash
變體。唯一的區別是date
用於格式化目前年份和月份。
您可以使用以下程式碼實現上述目標:#touch mycode.sh
#!/bin/bash export DD=$(date +%d) export YYYY=$(date | awk '{print $6}') export MM=$(date +%m) echo "$YYYY$MM$DD" if [[ $DD -eq 16 || $DD -eq 01 ]];then echo "$DD" else echo " The days are not 1st or 16th " fi #sh mycode.sh
輸出/輸出
20200303