unix shell脚本获取第n个工作日

时间:2016-08-01 21:14:45

标签: shell unix ksh

引用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作为脚本名称,导致语法错误。请帮忙。

2 个答案:

答案 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的输出很难解析,因为:

  1. 这是对的。
  2. 它的空间分隔。
  3. 一个或两个数字日期表示两个或一个分隔空格。
  4. 每月第一天有更多领先的空间。
  5. 如果没有-h选项,解析将无法正常工作,(关闭'今天'突出显示)。