Unix Shell 程序来检测现在是哪半月。月份中的某一天 (dom) -le 16

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"

答案1

使用bash4.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打印当前年份和月份,然后将01or16字符串添加到其末尾。

-1调用的参数使printf格式%(...)T字符串使用当前时间作为格式化的时间戳(如果您使用的是bash4.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之间的一个以零填充的整数。请注意,在算术上下文(语句)中使用此类值会将这些值解释为0131if0107八进制值,并且会产生08和 的错误09(这些是无效的八进制数)。这就是为什么我使用来获取介于和%e之间的非零填充整数。131

关于最后一点:我也可以使用

printf -v day '%(%d)T' -1

获得01和之间的零填充值31,但随后我需要使用

if [[ 10#$day -ge 16 ]]; then

强制 shell 将字符串解释为十进制整数而不是八进制整数。


作为/bin/sh脚本(也适用于bash4.2 之前的版本,例如bashmacOS 上的默认 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"

标准shshell 没有 的%(...)T格式字符串bash,因此我们被迫使用 来date进行日期字符串格式化。它也用于[ ... ]测试而不是[[ ... ]](并且变量需要在其中加双引号)。

更紧凑的版本/bin/sh

#!/bin/sh

day=$( date +%e )
printf '%s%.2d\n' "$(date +%Y%m)" "$(( (day < 16) ? 1 : 16 ))"

这个更紧凑的版本源自紧凑型bash变体。唯一的区别是date用于格式化当前年份和月份。

答案2

您可以使用下面的代码来实现上述目的:#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

答案3

上面的方法有效,这是我的有效代码:

export day=$(date +%d)
export YR=$(date | awk '{print $6}')
export MM=$(date +%m)
echo $DY
echo "$YR$MM$day"

if [[ $day -ge 16 ]]; then
    day=16
else
day=01
fi
printf '%(%Y%m)T%s\n' -1 "$day"



export FD="$YR$MM$day"
echo $FD

答案4

dd=$(date +%d)
# values 08 and 09 will not work with arithmetic the way you expect
d=${dd#0}         # remove any leading 0
if [ "$d" -ge 16 ] ;then
  half=16
else
  half=01
fi
date "+%Y%m$half"

我认为这段代码是最容易理解的。唯一的复杂之处在于使用 shell 算术表达式以及以 digital 开头的数字0,除非您以前遇到过,否则您可能不会意识到这一点。的格式字符串date记录在strftime(3)联机帮助页中。请注意, date( 或)的实现printf不理解%e转换规范。该${dd#0}构造记录在bash(1)(或其他 shell)联机帮助页的“参数扩展”部分中。

相关内容