最终目标是设置一个变量 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
使用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
之间的一个以零填充的整数。请注意,在算术上下文(语句)中使用此类值会将这些值解释为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
用于格式化当前年份和月份。
答案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)联机帮助页的“参数扩展”部分中。