@Unix
我试图将每个月的第一个周二捕获到一个变量中,并试图在没有运气的情况下对其进行填充。
以下是我正在尝试的代码:
cal | sed -e 's/ \([1-9]\) /0\1 /g' -e 's/ \([1-9]\)$/0\1/' | awk 'NR>2{Sfields=7-NF; if (Sfields == 0 ) {printf "%d\n",$3;exit}}'
有人可以帮助我,我在这里缺少什么吗?
答案 0 :(得分:1)
# for monday calendar
cal -m1 | sed -n '1,2b;/^.\{3\} \{0,1\}\([0-9]\{1,2\}\) .*/ {s//0\1/;s/.*\([0-9]\{2\}\)$/\1/p;q;}'
# for sunday calendar
cal -s1 01 01 2015 | sed -n '1,2b;/^.\{6\} \{0,1\}\([0-9]\{1,2\}\) .*/ {s//0\1/;s/.*\([0-9]\{2\}\)$/\1/p;q;}'
cal
选项取决于系统(在Red Hat 6.6上进行测试),并表示-m
表示星期一作为第一天,-s
表示星期日(附加1
表示1个月的展示)。根据您指定的cal
输出行。0
,删除trailng char 感谢@Jotne关于第二周(第4行而不是第3周)第一天和第一天的第一天的所有评论
答案 1 :(得分:1)
此awk
应该:
cal | awk 'NR>2 && NF>4 {printf "%02d\n",$(NF-4);exit}'
03
确认其工作:
for i in {1..12}; do cal -m $i | awk 'NR>2 && NF>4 {printf "%02d\n",$(NF-4);exit}' ; done
06
03
03
07
05
02
07
04
01
06
03
01
或者您可以使用ncal
ncal | awk '/Tu/ {printf "%02d\n",$2}'
03
如果您喜欢可以指定星期名称的版本,
并且如果Monday
是一周的第一天,那么这个gnu awk
应该这样做:
cal | awk 'NR==2 {for (i=1;i<=NF;i++) {sub(/ /,"",$i);a[$i]=i}} NR>2 {if ($a["Tu"]~/[0-9]/) {printf "%02d\n",$a["Tu"];exit}}' FIELDWIDTHS="3 3 3 3 3 3 3 3"
03
它使用FIELDWITH
来确保月初的空列不会更改输出。
答案 2 :(得分:0)
我想我得到了答案。
cal | awk 'NR>2{Sfields=7-NF; if (Sfields == 0 ) {printf "%02d\n",$3;exit}}'
上述陈述可以。"%02d"
为我做了
答案 3 :(得分:0)
bash和日期。可能比解析cal慢:
y=2015
for m in {1..12}; do
for d in {01..07}; do
if [[ $(date -d "$y-$m-$d" +%w) -eq 2 ]]; then
echo $d
break
fi
done
done
转换为awk:会更快,因为它不必多次调用日期:
gawk -v y=2015 '
BEGIN {
for (m=1; m<=12; m++) {
for (d=1; d<=7; d++) {
t = mktime( y " " m " " d " 12 0 0" )
if (strftime("%w", t) == 2) {
printf "%02d\n", d
break
}
}
}
}
'