引用this unix.com thread上发布的解决方案以获取当月的第N个工作日,我尝试使用以下代码获取当月的第16个工作日,但它不起作用。
currCal=`/usr/bin/cal`
BUSINESS_DAYS=`echo $($currCal|nawk 'NR>2 {print substr($0,4,14)}' |tr "\n" " ")`
执行此操作时的错误是:
nawk:源代码行1上下文中的语法错误 NR> 2 {print>>> substr(test。<<<< sh,4,14)} nawk:来源第1行的非法声明
我猜测它需要$0
作为脚本名称,导致语法错误。请帮忙。
答案 0 :(得分:3)
上面的内容似乎存在一些问题。
首先,我同意@ John1024,为了得到你发布的nawk错误,你必须真正运行:
BUSINESS_DAYS=`echo $($currCal|nawk "NR>2 {print substr($0,4,14)}" |tr "\n" " ")`
在nawk脚本周围加上双引号。
此外,一旦解决了nawk错误,您将遇到使用currCal
的方式的问题。您将cal
命令的实际输出输入currCal
变量,但随后使用变量值(即cal
的输出)作为{{1}之前的命令而不是|
它进入管道或类似的东西。
这提出了另一个问题,即为什么在另一个子shell(外部`s)中对子shell命令(echo
部分)的结果使用echo
。
最后,您在上面显示的两行只会将当前月份的工作日列表转换为$()
变量。他们没有输出/保存第16天。
考虑到上述所有因素(以及更改为始终使用BUSINESS_DAYS
子shell语法),您可能需要以下调用之一:
如果你真的需要缓存当前月份的日历并希望拉多天:
$()
如果这只是一次又一次:
currCal="$(/usr/bin/cal)"
BUSINESS_DAYS="$(echo "${currCal}" | \
nawk 'NR>2 {print substr($0,4,14)}' | \
tr "\n" " ")"
DAY=16
DAYTH_DAY="$(echo "${BUSINESS_DAYS}" | nawk -v "day=${DAY}" '{ print $day }')
还有一点需要注意:如果完全用awk(/ nawk)完成,这里的处理可以简化,但我想坚持你已经选择的基本框架。
根据评论中的请求进行更新:
纯POSIX awk版本:
DAY=16
DAYTH_DAY="$(/usr/bin/cal | \
nawk 'NR>2 {print substr($0,4,14)}' | \
tr "\n" " " | \
nawk -v "day=${DAY}" '{ print $day }')"
是的,简化是一个意见问题,我相信有人可以使这更简洁。解释这是如何工作的:
跳过校准输出的标题:
DAY=16
DAYTH="$(cal | awk -v "day=${DAY}" '
(NR < 3) { next ; }
/^.[0-9 ]/ { $1="" ; }
/^ / || (NF == 7) { $NF="" ; }
{ hold=hold $0 ; }
END { split(hold,arr," ") ; print arr[day] ; }')"
对于星期日有日期的星期,修剪该星期日的日期:
(NR < 3) { next ; }
在星期日(一个月的第一周)或星期开始的整周七天的周数,修剪该星期六的星期日:
/^.[0-9 ]/ { $1="" ; }
一旦这些行只有工作日的日期,请将它们加入/^ / || (NF == 7) { $NF="" ; }
:
hold
最后,在空格上拆分{ hold=hold $0 ; }
,以便我们可以抓住第N天:
hold
答案 1 :(得分:1)
否awk
,只是软件工具:
set -- $(cal -h | rev | cut --complement -b-5,20- | rev | tail -n +3) ; \
shift 15 ; echo $1
输出:
22
cal
的输出很难解析,因为:
-h
选项,解析将无法正常工作,(关闭'今天'突出显示)。