Anzeige der Wochennummer in einem bestimmten Format mit ncal oder cal


15

Liebst du es nicht einfach, wenn zwei Befehle jeweils eines tun, das du willst, aber auch nicht beide?

Das ist was caltut. Schöne Formatierung. Es fehlen allerdings die Wochenzahlen:

$ 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              

Das ist was ncaltut. Seltsame Formatierung, aber mit Wochennummern:

$ 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   

Die Art der Ausgabe, die ich möchte, eigentlich eine Kreuzung zwischen calund 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

Antworten:


13

Wenn keiner dieser Befehle Ihren Anforderungen entspricht, können gcalSie stattdessen das tun, was Sie möchten.

Beispiel

$ 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

Gibt die Wochennummer in der letzten Spalte rechts aus.

Verweise


gcal --starting-day=Monday --with-week-numberPasst mehr zu meinen Bedürfnissen, aber dieses Tool ist großartig.
k0pernikus

9

Dies hebt das heutige Datum hervor und kann jeden Monat $1in der folgenden Form anzeigen : YYYY-mm-dd... Standardmäßig wird das heutige Datum verwendet

Es ist so eingestellt, dass ISO-Wochennummern angezeigt werden und der erste Wochentag der Montag ist.

#!/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)

Hier ist die Anzeige dieses Monats (mit 20Hervorhebung)

       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                

Ich habe das Iso-Problem nicht einmal bemerkt. Das reicht :)
k0pernikus

1
@ k0pernikus: Ich habe das Skript gerade geändert .. (ca. 35 Minuten , nachdem Sie den obigen Kommentar geschrieben) .. Es war immer gefangen auf 08und 09so interpretiert werden Oktal statt dezimal .. Es soll jetzt gut sein ...
Peter.O

7

Sie können verwenden, nlum die Zeilen zu nummerieren (das ist der Zweck des Programms :). Aber Sie müssen die erste Woche im Monat irgendwo extrahieren. Es kann von ncalselbst gemacht werden:

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

Wir fügen dies als Parameter in nldie Option -v(Startzeilennummer) ein und teilen es nur Zahlenzeilen mit Zahlen oder Leerzeichen mit.

$ 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

Das ist alles furchtbar zerbrechlich. Auf jeden Fall calfunktioniert es , wenn Sie keine erweiterten Optionen benötigen . Sie können es in eine Datei einfügen und ersetzen"$@" wo ich es abgelegt habe 2 2012.


EDIT: Aber das ist FALSCH! Mir ist gerade aufgefallen, dass die erste Januarwoche die Nummer 52 oder 53 haben kann! Wir müssen also entweder eine Ausnahme für Januar machen oder einfach alle Wochennummern aus extrahieren ncalund auf die Ausgabe von anwenden cal.

Dies ist die Lösung, die ich ursprünglich dachte, aber ich dachte (fälschlicherweise), ich würde es mit vereinfachen nl. Dabei werden pasteDateien nebeneinander zusammengeführt. Da es keine Datei gibt, müssen wir den Bashismus verwenden <(...). das wollte ich vermeiden.

Unsere erste "Datei" ist eine Liste der Wochennummern mit zwei Leerzeilen am Anfang:

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


52
 1
 2
 3
 4
 5

Der zweite ist nur die Ausgabe von cal. Alles in allem als Parameter für 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

Viel chaotischer und unvereinbarer als der andere. En fin ...


Nicht so toll :-/. Siehe meine Bearbeitung.
Angus

7

Generieren Sie die Wochenfolge mit ncalund verwenden Sie diese, pasteum beide Ausgaben nebeneinander zu haben.

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

Wenn Sie keine Tabulatoren als Trennzeichen haben möchten, fügen Sie einfach etwas wie hinzu sed 's/\t/ /'


Bearbeiten : viel einfacher, ohne sich um Tabs kümmern zu müssen:

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

Elegant und verkörpert viele der 17 Unix-Regeln von ESR . Sollte die akzeptierte Antwort sein, da sie die Ausgabe von calund wirklich kombiniert ncal(andere Ansätze replizieren das Verhalten von entweder caloder ncal).
Bischof

4

Eine Möglichkeit, Perl zu verwenden (meine Ausgabesprache des calBefehls ist Spanisch, aber ich hoffe, das Ergebnis weicht nicht von Englisch ab):

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

Ausgabe:

       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

Erläuterung:

-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.

Wie wird dies für die nächsten Monate funktionieren? Die Februarwochen beginnen nicht wieder mit 1, sie beginnen entweder mit 5/6, ähnlich wie der März mit 9/10.
Nikhil Mulley

cal 02 2012, ist das fehlgeschlagen ??
Nikhil Mulley

@ Nikhil: Ich verstehe nicht, was du meinst. Können Sie versuchen, es genauer zu erklären? Schlägt das Skript fehl cal 02 2012? Es schien in meinem Test zu funktionieren.
Birei

@ Nikhil: Ah, ok. Ich habe die Frage falsch verstanden. Es bedeutet absolute Wochenzahlen und nicht relativ zu jedem Monat. Ich werde meine falsche Antwort in einer Weile löschen.
Birei

1
cool .. nicht die Antwort löschen, bitte bewahren Sie es als Referenz.
Nikhil Mulley

1

Ohne genügend Wiederholungen, um die Antwort von slm zu kommentieren , kann gcal unter Mac OS mit installiert werden brew install gcal.

(Ich fand die Antwort zuerst hier, dann diese Antwort auf Frage anders, aber der Unix-Antwort fehlten alle Informationen, die ich brauchte, um auf dem Mac zu installieren.)


0

Hier ist meine Lösung, die im Code kürzer ist und auch für andere Daten als den aktuellen Monat funktioniert. Entschuldigung für die US-Leute, dies verwendet das ISO-Format, dh der erste Wochentag ist Montag. Dies erfolgt mit der Option -m für cal und der Option% V für date

#!/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

Ich habe dieses Skript erstellt, um einen Dienstkalender für Teams zu erstellen. Es generiert einen Kalender mit Wochennummern und weist diesen Namen zu (einfach Round-Robin). Nachdem die Ausgabe gedruckt wurde, müssen Sie sie nur kopieren, um sie zu übertreffen und "Text in Spalte" zu schreiben. und wieder "text to column" in der ersten Spalte mit der Option "fixed" ausführen. Der Vorteil dieses Kalenders (im Vergleich zur horizontalen Ausrichtung) besteht darin, dass Sie den automatischen Filter (Alt + dff) verwenden und nur Ihre Wochen finden können.

#! / usr / bin / ksh
y = 2017
Set-A Team1 Petars Justas Richard Jukka Jesper
Set-A Team2 Modestas Timo Mats Andreas

i1 = 0
i2 = 0
wn = 1
own = 1

Echo "WN Monat Mo Di Mi Do Fr Sa So; Team1; Team2"
ycal = `für m in 1 2 3 4 5 6 7 8 9 10 11 12
tun
IFS =
        cal -m $ m $ y | egrep -v "Mo | ^ $" | während die Zeile gelesen wird
        tun
                echo $ line | grep -q $ y && mname = $ line || print $ mname $ line | sed 's /' $ y '//'
        erledigt
fertig`
IFS =
Geben Sie "$ ycal" | ein, während Sie Zeile2 lesen
tun
IFS =
        echo "$ line2" | grep -v "1 2 3 4 5 6 7" | egrep -q "* 1 | * 1 $" || let wn ++
        [$ own -ne $ wn] && {\
                [$ i1 -eq $ {# team1 [@]} - 1] && i1 = 0 || let i1 ++; \
                [$ i2 -eq $ {# team2 [@]} - 1] && i2 = 0 || let i2 ++; }
        printf '% 2s% s;% s;% s \ n' $ wn $ line2 $ {team1 [$ i1]} $ {team2 [$ i2]}
        own = $ wn
erledigt

Sorry, Code ein bisschen böse ... und keine Kommentare ... aber es funktioniert gut;)


0

Ich möchte nicht wirklich installieren gcal, und ich konnte es auf meinem System nicht richtig zum Laufen bringen. Ohne gcal ist die Antwort von funollet in der Tat die beste Lösung. Ich kann es nur ein klein wenig verändert , so dass es auch wie Konserven Formatierung Tag Highlight , Farben etc. , um die Verwendung von scriptBefehl. Ich habe auch überflüssige Zeichen entfernt, so dass es als Alias ​​geeignet ist:

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

Oder durch caleine neue Funktion ersetzen . Damit können Sie jedoch keine Dinge wie tun cal -3. Sie erhalten die richtigen Wochen, aber sie sind nicht richtig ausgerichtet. Eine einfache, aber nicht vollständige Lösung besteht darin, zu überprüfen, ob der calAufruf ohne Argumente erfolgt.

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
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.