แสดงหมายเลขของสัปดาห์ในบางรูปแบบโดยใช้ ncal หรือ cal


16

คุณไม่เพียงแค่รักมันเมื่อทั้งสองคำสั่งทำในสิ่งที่คุณต้องการ แต่ไม่ทำทั้งสองอย่าง?

นี่คือสิ่งที่calไม่ การจัดรูปแบบที่ดี ไม่มีตัวเลขสัปดาห์แม้ว่า:

$ cal
    January 2012      
Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30 31              

นี่คือสิ่งที่ncalไม่ การจัดรูปแบบแปลก ๆ แต่มีตัวเลขเป็นสัปดาห์:

$ ncal -w
    January 2012      
Su  1  8 15 22 29   
Mo  2  9 16 23 30   
Tu  3 10 17 24 31   
We  4 11 18 25      
Th  5 12 19 26      
Fr  6 13 20 27      
Sa  7 14 21 28      
    1  2  3  4  5   

ชนิดของเอาต์พุตที่ฉันต้องการจริงๆแล้วเป็นลูกผสมระหว่างcalและncal -w:

$ cal --magik-calendar-week-option
      January 2012      
   Su Mo Tu We Th Fr Sa  
1   1  2  3  4  5  6  7  
2   8  9 10 11 12 13 14  
3  15 16 17 18 19 20 21  
4  22 23 24 25 26 27 28  
5  29 30 31

คำตอบ:


13

หากคำสั่งเหล่านี้ไม่ตรงกับความต้องการของคุณคุณสามารถใช้gcalเพื่อทำสิ่งที่คุณต้องการแทน

ตัวอย่าง

$ gcal -K

      April 2014
 Su Mo Tu We Th Fr Sa CW
        1  2  3  4  5 13
  6  7  8  9 10 11 12 14
 13 14 15 16 17 18 19 15
 20 21 22 23 24 25 26 16
 27 28 29 30          17

พิมพ์หมายเลขสัปดาห์ในคอลัมน์สุดท้ายทางด้านขวา

อ้างอิง


gcal --starting-day=Monday --with-week-numberเหมาะกับความต้องการของฉันมากกว่านี้เครื่องมือนี้ยอดเยี่ยม
k0pernikus

9

ไฮไลต์วันที่วันนี้และสามารถแสดงเดือนใด ๆ ผ่านทาง$1ในรูปแบบ: YYYY-mm-dd... มันเริ่มต้นที่วันที่วันนี้

มีการตั้งค่าให้แสดงหมายเลขสัปดาห์ ISO และวันทำงานวันแรกเป็นวันจันทร์

#!/bin/bash
# Input reference date is expected in  'YYYY-mm-dd' format
#
today=($(date '+%Y %m %d')); Y=0; m=1; d=2                # establish today's date
[[ -z $1 ]] && ref=(${today[@]}) || ref=(${1//-/ })       # get input date
dNbA=$(date --date="$(date +%Y-%m-01)" +'%u')             # day-number of 1st day of reference month
today[m]=$((10#${today[m]})); ref[m]=$((10#${ref[m]}))    # remove leading zero (octal clash)
today[d]=$((10#${today[d]})); ref[d]=$((10#${ref[d]}))    # remove leading zero (octal clash)
nxtm=$(( ref[m]==12 ?1       :ref[m]+1 ))                 # month-number of next month
nxtY=$(( ref[m]==12 ?ref[Y]+1:ref[Y]   ))                 # year-number of next month
nxtA="$nxtY-$nxtm-1"                                      # date of 1st day of next month
refZ=$(date --date "$(date +$nxtA) yesterday" +%Y-%m-%d)  # date of last day of reference  month
days=$(date --date="$refZ" '+%d')                         # days in reference month

h1="$(date --date="${ref[Y]}-${ref[m]}-${ref[d]}" '+%B %Y')" # header 1 
h2="Mo Tu We Th Fr Sa Su"                                    # header 2 
printf "    %$(((${#h2}-${#h1}-1)/2))s%s\n" " " "$h1"
printf "    %s\n" "$h2"
# print week rows   
printf "%2d  " "$((10#$(date -d "$(date +${ref[Y]}-${ref[m]}-01)" +'%V')))" # week-number (of year) with suppressed leading 0
printf "%$(((dNbA-1)*3))s"  # lead spaces (before start of month)
dNbW=$dNbA  # day-number of week
dNbM=1      # day-number of month
while ((dNbM <= days)) ;do
    if (( today[Y]==ref[Y] &&  
          today[m]==ref[m] && 
          today[d]==dNbM )) ;then
        printf "\x1b[7m%2d\x1b[0m " "$dNbM" # highlight today's date 
    else
        printf "%2d " "$dNbM"
    fi
    ((dNbM++))
    if ((dNbW  >=7)) ;then
        cdate=$((10#$(date -d "$(date +${ref[Y]}-${ref[m]}-$dNbM)" +'%V'))) # remove leading zero (octal clash)
        printf "\n%2d  " "$cdate" # week-number of year
        dNbW=0
    fi
    ((dNbW++))
done
printf "%$(((8-dNbW)*3))s\n" # trailing spaces (after end of month)

นี่คือการแสดงผลของเดือนนี้ (พร้อม20ไฮไลต์)

       January 2012
    Mo Tu We Th Fr Sa Su
52                     1 
 1   2  3  4  5  6  7  8 
 2   9 10 11 12 13 14 15 
 3  16 17 18 19 20 21 22 
 4  23 24 25 26 27 28 29 
 5  30 31                

ฉันไม่ได้สังเกตเห็นปัญหา iso ที่จะทำ :)
k0pernikus

1
@ k0pernikus: ฉันเพิ่งแก้ไขสคริปต์ .. (ประมาณ 35 นาทีหลังจากที่คุณโพสต์ความคิดเห็นด้านบน) .. มันติด08และ09ถูกตีความว่าเป็นฐานแปดแทนทศนิยม .. ตอนนี้น่าจะดี ...
Peter.O

7

คุณสามารถใช้nlเพื่อกำหนดหมายเลขบรรทัด (นั่นคือจุดประสงค์ของโปรแกรม :) แต่คุณต้องแยกสัปดาห์แรกของเดือนออกจากที่ไหนสักแห่ง มันสามารถทำได้จากncalตัวเอง:

$ ncal -w 2 2012 | tail -1 | awk '{print $1}'
5

เราแทรกสิ่งนี้เป็นพารามิเตอร์nlของตัวเลือก-v(หมายเลขบรรทัดเริ่มต้น) และบอกให้เฉพาะบรรทัดตัวเลขที่มีตัวเลขหรือช่องว่าง

$ cal 2 2012 | nl -bp'^[0-9 ]\+$' -w2 -s'  ' -v$(ncal -w 2 2012 | tail -1 | awk '{print $1}')
       February 2012
    Su Mo Tu We Th Fr Sa
 5            1  2  3  4
 6   5  6  7  8  9 10 11
 7  12 13 14 15 16 17 18
 8  19 20 21 22 23 24 25
 9  26 27 28 29

ทั้งหมดนี้มีความเปราะบางอย่างยิ่งยวด อย่างไรก็ตามหากคุณไม่ต้องการcalตัวเลือกขั้นสูงเพิ่มเติมมันจะทำงานได้ คุณสามารถวางไว้ในแฟ้มและแทนที่ที่ผมใส่"$@"2 2012


แก้ไข: แต่นี่มันผิด! ฉันเพิ่งสังเกตเห็นว่าสัปดาห์แรกของเดือนมกราคมสามารถมีหมายเลข 52 หรือ 53! ดังนั้นเราก็อาจจะต้องทำให้มีข้อยกเว้นสำหรับเดือนมกราคมหรือเพียงแค่ดึงทุกหมายเลขสัปดาห์และนำไปใช้กับการส่งออกของncalcal

นี่คือวิธีการแก้ปัญหาที่ผมคิดเดิม แต่ผมคิดว่า (สมควร) nlฉันจะลดความซับซ้อนของมันโดยใช้ มันใช้pasteซึ่งรวมไฟล์เคียงข้างกัน เนื่องจากไม่มีไฟล์ใด ๆ เราจึงต้องใช้ความนิยม<(...)นั้น นั่นคือสิ่งที่ฉันพยายามหลีกเลี่ยง

"ไฟล์" แรกของเราจะเป็นรายการหมายเลขสัปดาห์โดยมีสองบรรทัดว่างในตอนเริ่มต้น:

$ printf '   \n   \n' && printf '%2d \n' $(ncal -w 1 2011 | tail -1)


52
 1
 2
 3
 4
 5

calคนที่สองเพียงแค่การส่งออกของ ทั้งหมดเข้าด้วยกันเป็นพารามิเตอร์ไปที่paste:

$ paste -d' ' <(printf '   \n   \n' && printf '%2d \n' $(ncal -w 1 2011 | tail -1)) <(cal 1 2011)
        January 2011
    Su Mo Tu We Th Fr Sa
52                     1
 1   2  3  4  5  6  7  8
 2   9 10 11 12 13 14 15
 3  16 17 18 19 20 21 22
 4  23 24 25 26 27 28 29
 5  30 31

เมสเซอร์เยอะกว่าและเข้ากันไม่ได้อีกอันหนึ่ง กำลัง ...


ไม่ค่อยดีนัก: - / ดูการแก้ไขของฉัน
angus

7

สร้างลำดับสัปดาห์ด้วยncalและใช้pasteเพื่อให้ได้ผลลัพธ์ทั้งคู่ขนานกัน

$ paste <(echo; echo; ncal -w | tail -1 | xargs -n1 printf '%2d\n') <(cal)

หากคุณไม่ชอบมีแท็บเป็นตัวคั่นเพียงเพิ่มสิ่งที่ต้องการ sed 's/\t/ /'


แก้ไข : วิธีที่ง่ายกว่าไม่จำเป็นต้องสนใจแท็บ:

$ paste -d' ' <((echo -n '   '; ncal -w | tail -1 )| fold -w 3) <(cal)

หรูหราและคาดเดาหลายESR 17 กฎยูนิกซ์ ควรจะเป็นคำตอบที่ได้รับการยอมรับตามจริงรวมการส่งออกของcalและncalอื่น ๆ (แนวทางพฤติกรรมซ้ำอย่างใดอย่างหนึ่งcalหรือncal)
บิชอป

4

วิธีหนึ่งในการใช้ Perl (ภาษาเอาต์พุตของcalคำสั่งคือภาษาสเปน แต่ฉันหวังว่าผลลัพธ์จะไม่แตกต่างจากภาษาอังกฤษ):

$ cal | perl -pe 'if ( m/\A\s*\d/ ) { s/\A/++$i . qq[ ] x 2/e } else { s/\A/qq[ ] x 3/e }'

เอาท์พุท:

       enero de 2012   
   lu ma mi ju vi sá do
1                     1
2   2  3  4  5  6  7  8
3   9 10 11 12 13 14 15
4  16 17 18 19 20 21 22
5  23 24 25 26 27 28 29
6  30 31

คำอธิบาย:

-pe                     # For every input line from previous pipe, execute  next
                        # instructions and print to output.
if ( m/\A\s*\d/ )       # If line begins with a digit omitting spaces...
s/\A/++$i . qq[ ] x 2/e # Insert at the beginning of the line a counter plus two spaces.
else                    # else...
s/\A/qq[ ] x 3/e        # Insert three spaces at the beginning of the line.

จะใช้งานได้อย่างไรในอีกไม่กี่เดือนข้างหน้า สัปดาห์กุมภาพันธ์ไม่เริ่มจากอีกครั้ง 1 พวกเขาเริ่มต้นจาก 5/6 ในทำนองเดียวกันมีนาคมจะมาจาก 9/10
Nikhil Mulley

cal 02 2012 มันจะล้มเหลวไหม
Nikhil Mulley

@Nikhil: ฉันไม่เข้าใจว่าคุณหมายถึงอะไร คุณลองอธิบายให้ลึกซึ้งกว่านี้ได้ไหม? สคริปต์ล้มเหลวด้วยcal 02 2012หรือไม่ ดูเหมือนว่าจะทำงานในการทดสอบของฉัน
Birei

@Nikhil: อ่าโอเค ฉันคิดถึงคำถาม มันหมายถึงตัวเลขสัปดาห์ที่แน่นอนและไม่สัมพันธ์กับแต่ละเดือน ฉันจะลบคำตอบที่ผิดไปครู่หนึ่ง
Birei

1
cool..do ไม่ลบคำตอบโปรดเก็บไว้สำหรับการอ้างอิง
Nikhil Mulley

1

โดยไม่ต้องตัวแทนพอที่จะแสดงความคิดเห็นในคำตอบโดย SLM, GCalสามารถติดตั้งบนระบบปฏิบัติการ Mac OS brew install gcalโดยใช้

(ฉันพบคำตอบที่นี่ก่อนจากนั้นคำตอบนี้ถามแตกต่างกัน แต่คำตอบ unix ขาดข้อมูลทั้งหมดที่ฉันต้องการเพื่อติดตั้งบน mac)


0

นี่คือโซลูชันของฉันซึ่งสั้นกว่าในรหัสและทำงานได้ดีสำหรับวันอื่น ๆ นอกเหนือจากเดือนปัจจุบัน ขออภัยสำหรับชาวอเมริกันใช้รูปแบบ ISO นั่นคือวันที่ 1 ของสัปดาห์คือวันจันทร์ เสร็จสิ้นด้วยตัวเลือก -m สำหรับ cal และตัวเลือก% V สำหรับวันที่

#!/bin/bash
if [ "$1" = "" ]
then
  when="now"
else
  when="$1"
fi
y=$(date --date "$when" +%Y )
if [ $? -ne 0 ]
then
  exit
fi
m=$(date --date "$when" +%m )
w=$(date --date $(printf %4d%02d01 $y $m) +%V)
cal -m $m $y |
  awk -v w=$w '
    NR>2{ww=w++}
    $0!=""{printf "%2s %s\n", ww , $0}
  '

0

ฉันทำสคริปต์นี้เพื่อสร้างปฏิทินประจำหน้าที่สำหรับทีม มันสร้างปฏิทินที่มีหมายเลขสัปดาห์และกำหนดชื่อให้กับพวกเขา (เพียงรอบโรบิน) หลังจากพิมพ์เอาต์พุตแล้วคุณต้องคัดลอกไปยัง excel และทำ "text to column" โดย; และดำเนินการอีกครั้ง "ข้อความถึงคอลัมน์" ในคอลัมน์แรกโดยใช้ตัวเลือก "คงที่" ประโยชน์ของปฏิทินนี้ (เปรียบเทียบกับการวางในแนวนอน) คือคุณสามารถใช้ตัวกรองอัตโนมัติ (Alt + dff) และค้นหาเฉพาะสัปดาห์ของคุณ

#! / usr / bin / ksh
การ y = 2017
ชุด -A team1 Petars Justas Richard Jukka Jesper
ชุด -A team2 Modestas Timo Mats Andreas

i1 = 0
i2 = 0
WN = 1
ตัวเอง = 1

echo "WN เดือน Mo Tu เรา Th Fr Sa Su; Team1; Team2"
ycal = `สำหรับ m ใน 1 2 3 4 5 6 7 8 9 10 11 12
ทำ
ไอเอฟเอ =
        cal -m $ m $ y | egrep -v "Mo | ^ $" | ในขณะที่อ่านบรรทัด
        ทำ
                echo $ line | grep -q $ y && mname = $ line || พิมพ์ $ mname $ line | sed 's /' $ y '//'
        เสร็จแล้ว
done`
ไอเอฟเอ =
echo "$ ycal" | ขณะอ่าน line2
ทำ
ไอเอฟเอ =
        echo "$ line2" | grep -v "1 2 3 4 5 6 7" | egrep -q "* 1 | * 1 $" || ให้ wn ++
        [$ own -ne $ wn] && {\
                [$ i1 -eq $ {# team1 [@]} - 1] && i1 = 0 || ให้ i1 ++; \
                [$ i2 -eq $ {# team2 [@]} - 1] && i2 = 0 || ให้ i2 ++; }
        พิมพ์ '% 2s% s;% s;% s \ n' $ wn $ line2 $ {ทีม 1 [$ i1]} $ {ทีม 2 [$ i2]}
        เจ้าของ = $ WN
เสร็จแล้ว

ขออภัยรหัสน่ารังเกียจเล็กน้อย ... และไม่มีความคิดเห็น ... แต่ใช้งานได้ดี;)


0

ฉันไม่ต้องการติดตั้งgcalและไม่สามารถทำให้มันทำงานบนระบบของฉันได้ ดังนั้นหากไม่มี gcal คำตอบของ funolletจึงเป็นทางออกที่ดีที่สุด ฉันเพียงแค่เปลี่ยนมันเล็กน้อยเพื่อที่จะยังรักษารูปแบบเช่นวัน ไฮไลท์ , สีฯลฯ โดยใช้scriptคำสั่ง ฉันยังลบอักขระที่ซ้ำซ้อนออกไปทำให้เหมาะกับนามแฝงเช่น:

alias today="paste -d' ' <((echo ' '{,};ncal -w|tail -1)|fold -w3) <(script /dev/null -qc cal)"

หรือแทนที่calด้วยฟังก์ชั่นใหม่ cal -3แต่กับเรื่องนี้คุณไม่สามารถทำสิ่งที่ชอบ คุณได้รับสัปดาห์ที่ถูกต้อง แต่ไม่สอดคล้องกัน วิธีการแก้ปัญหาที่เรียบง่าย แต่ไม่สมบูรณ์คือการตรวจสอบว่าcalมีการเรียกใช้โดยไม่มีอาร์กิวเมนต์ดังนี้:

function cal {
    if [[ $# -eq 0 ]]; then
        paste -d' ' <((echo ' '{,};ncal -w $@|tail -1)|fold -w3) <(script /dev/null -qc "cal $@")
    else
        /usr/bin/cal "$@"
    fi
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.