Ncal veya cal kullanarak haftanın numarasını belirli formatta görüntüleme


16

İki komutun her biri istediğiniz bir şeyi yaptığında değil, her ikisinin de ikisini birden yapması hoşunuza gitmiyor mu?

İşte calböyle. Güzel biçimlendirme. Ancak hafta sayıları eksik:

$ 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              

İşte ncalböyle. Tuhaf biçimlendirme, ancak hafta numaralarıyla:

$ 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   

İstediğim çıktı türü, aslında calve arasında bir melez 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

Yanıtlar:


13

Bu komutların hiçbiri ihtiyaçlarınızı karşılamıyorsa, gcalbunun yerine istediğinizi yapmak için kullanabilirsiniz .

Misal

$ 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

Son sütundaki hafta numarasını sağa yazdırır.

Referanslar


gcal --starting-day=Monday --with-week-numberbenim ihtiyaçlarına daha uygun henüz bu araç harika.
k0pernikus

9

Bu, bugünün tarihini vurgular ve herhangi bir ayı $1şu biçimde görüntüleyebilir: YYYY-mm-dd... Varsayılan olarak bugünün tarihini gösterir

ISO hafta numaralarını gösterecek şekilde ayarlanmıştır ve ilk hafta içi pazartesi günüdür.

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

İşte bu ayın ekranı ( 20vurgulanmış olarak)

       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                

İzo meselesini bile fark etmedim. Yapacak :)
k0pernikus

1
@ k0pernikus: Ben sadece senaryoyu .. (yukarıdaki yorumu yayınlayan yaklaşık 35 dakika sonra) .. O üzerinde yakalanmış başlamıştı modifiye ettik 08ve 09olarak yorumlanmasını sekizlik yerine ondalık O ... ince şimdi olacak .. gerektiğini
Peter.O

7

nlSatırları numaralandırmak için kullanabilirsiniz (programın amacı budur :). Ancak ayın ilk haftasını bir yerden çıkarmanız gerekiyor. Kendinden yapılabilir ncal:

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

Bunu, nlseçeneğine -v(başlangıç ​​satırı numarası) bir parametre olarak ekleriz ve yalnızca sayı veya boşluk içeren sayı satırlarına söyleriz.

$ 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

Ancak bunların hepsi çok kırılgan. Her neyse, caldaha gelişmiş seçeneklere ihtiyacınız olmayacaksa işe yarayacaktır. Bir dosyaya "$@"koyabilir ve yerine koyduğum yeri değiştirebilirsiniz 2 2012.


EDIT: Ama bu YANLIŞ! Ocak ayının ilk haftasının 52 veya 53 numaralı olabileceğini fark ettim! Bu yüzden ya sadece Ocak ayı için bir istisna yapmalıyız, ya da sadece tüm hafta sayılarını ncalçıkarmalı ve çıktılarına uygulamalıyız cal.

Başlangıçta düşündüğüm çözüm bu, ama (hatalı olarak) kullanarak basitleştireceğimi düşündüm nl. pasteDosyaları yan yana birleştiren kullanır . Herhangi bir dosya olmadığından bashizmi kullanmak zorundayız <(...); Bundan kaçınmaya çalışıyordum.

İlk "dosyamız", başında iki boş satır bulunan hafta sayılarının bir listesi olacaktır:

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


52
 1
 2
 3
 4
 5

İkincisi, sadece çıktı cal. Hep birlikte, parametre olarak 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

Diğeri çok daha karışık ve uyumsuz. Tamam ...


Çok iyi değil :-/. Düzenlememe bakın.
angus

7

Her iki çıktıyı yan yana tutmak için hafta sırasını oluşturun ncalve kullanın paste.

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

Sınırlayıcı olarak sekmelere sahip olmaktan hoşlanmıyorsanız, yalnızca sed 's/\t/ /'


Düzenleme : çok daha basit, sekmelere dikkat etmenize gerek yok:

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

Zarif ve ESR'nin 17 Unix Kuralının çoğunu içeriyor . Kabul edilen cevap olmalıdır ve gerçekten çıktısını birleştirir calve ncal(diğer yaklaşımlar ya calda davranışlarını çoğaltır ncal).
Piskopos

4

Perl'i kullanmanın bir yolu ( calkomutun çıkış dili İspanyolca, ancak umarım sonuç İngilizce'den farklı değildir):

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

Çıktı:

       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

Açıklama:

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

sonraki aylarda bu nasıl olacak. Şubat haftaları tekrar başlamaz 1, 5 / 6'dan başlayarak benzer şekilde Mart 9 / 10'dan başlayacak.
Nikhil Mulley

cal 02 2012, bu başarısız olacak mı ??
Nikhil Mulley

@Nikhil: Ne demek istediğini anlamıyorum. Daha derinlemesine açıklamaya çalışabilir misiniz? Komut dosyası ile başarısız mı cal 02 2012? Testimde çalışıyor gibiydi.
Birei

@Nikhil: Ah, tamam. Soruyu yanlış anladım. Mutlak hafta sayıları anlamına gelir ve her aya göre değil. Bir süredir yanlış cevabımı sileceğim.
Birei

1
cool.. Cevabı silmeyin, lütfen referans için saklayın.
Nikhil Mulley

1

Açıklamanın yeterli temsilcisi olmadan cevap slm, gcal kullanarak Mac OS üzerinde kurulabilir brew install gcal.

(Önce cevabı burada buldum, daha sonra bu soruyla ilgili farklı cevap verdim, ancak unix cevabı, mac'e yüklemem için gereken tüm bilgileri içermiyordu.)


0

İşte benim kod daha kısa ve geçerli ayın dışındaki diğer tarihler için iyi çalışır benim çözüm. ABD halkı için üzgünüm, bu ISO formatını kullanıyor, yani haftanın 1. günü pazartesi. Bu, cal için -m seçeneği ve tarih için% V seçeneği ile yapılır

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

Bu senaryoyu ekipler için görev takvimi oluşturmak üzere yaptım. Hafta numaralarıyla takvim oluşturur ve bunlara adlar atar (yalnızca yuvarlak). Çıktı yazdırıldıktan sonra sadece excel ve "sütuna metin" tarafından kopyalamak gerekir; ve bir kez daha "sabit" seçeneğini kullanarak ilk sütunda "sütundan metne" işlemini gerçekleştirin. Bu takvimin yararı (yatay yönlendirmeyle karşılaştırıldığında) otomatik filtreyi (Alt + dff) kullanabilmeniz ve yalnızca haftalarınızı bulabilmenizdir.

#! / Usr / bin / ksh
= 2017 y
set -A takım1 Petars Justas Richard Jukka Jesper
set -A takım2 Modestas Timo Mats Andreas

i1 = 0
i2 = 0
wn = 1
Kendi = 1

echo "WN Ay Mo Tu We Th Fr Sa Su; Takım1; Takım2"
ycal = `m için 1 2 3 4 5 6 7 8 9 10 11 12
yapmak
IFS =
        cal -m $ m $ y | egrep -v "Mo | ^ $" | okunurken satır
        yapmak
                echo $ line | grep -q $ y && mname = $ satır || print $ mname $ line | sed 's /' $ y '//'
        tamam
done`
IFS =
echo "$ ycal" | satır 2 okunurken
yapmak
IFS =
        echo "$ line2" | grep -v "1 2 3 4 5 6 7" | egrep -q "* 1 | * 1 $" || wn ++ 'ın olsun
        [$ own -ne $ wn] && {\
                [$ i1 -eq $ {# team1 [@]} - 1] && i1 = 0 || i1 ++; \
                [$ i2 -eq $ {# team2 [@]} - 1] && i2 = 0 || i2 ++; }
        printf '% 2s% s;% s;% s \ n' $ wn $ line2 $ {ekip1 [$ i1]} $ {ekip2 [$ i2]}
        = $ Wn sahibi
tamam

Üzgünüm, kod biraz kötü ... ve yorum yok ... ama iyi çalışıyor;)


0

Gerçekten yüklemek istemiyorum gcalve sistemimde düzgün çalışmasını sağlayamadım. Yani gcal olmadan funollet'in cevabı gerçekten en iyi çözümdür. Komutu kullanarak gün vurgulama , renkler vb. Biçimlendirmeyi de koruyacak şekilde biraz değiştirdim script. Ayrıca gereksiz karakterleri kaldırdım, bu şekilde takma ad olarak uygun hale getirdim:

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

Veya calyeni bir işlevle değiştirin . Bununla birlikte, bunun gibi şeyler yapamazsınız cal -3. Doğru haftaları alırsınız, ancak doğru şekilde hizalanmazlar. Basit ama tam olmayan bir çözüm, calargüman olmadan çağrılıp çağrılmadığını kontrol etmektir, şöyle:

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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.