ncalまたはcalを使用して特定の形式で週の数を表示する


15

2つのコマンドがそれぞれ必要なことを1つ実行し、両方を実行しない場合に、単にそれを愛していませんか?

これが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   

私が欲しいの出力の種類、間に実際に雑種calncal -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 16

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-issueにさえ気づきませんでした。:)
k0pernikus

1
@ k0pernikus:私はちょうど...それは上巻き込まれた(上記のコメントを掲載約35分後)..スクリプトを変更した0809として解釈されるの代わりに、小数 ...今は問題ないはずです...
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た場所を置き換えることができます。


編集:しかし、これは間違っています!1月の最初の週には52番または53番があることに気付いただけです!そのため、1月の例外を作成するか、すべての週番号を抽出ncalしての出力に適用するだけですcal

これは元々考えていた解決策ですが、(間違って)を使用して単純化すると考えましたnl。を使用してpaste、ファイルを並べてマージします。ファイルがないため、bashismを使用する必要があります<(...)ます。それが私が避けようとしていたことです。

最初の「ファイル」は週番号のリストで、先頭に2つの空の行があります。

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


52
 1
 2
 3
 4
 5

2番目は、の出力のみです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

他のものよりもずっと厄介で互換性がありません。エンフィン...


それほど良くない:-/。編集をご覧ください。
アンガス

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のUnixルールのます。caland の出力を実際に結合するため、受け入れられた答えである必要がncalあります(calまたはのいずれかの動作を複製する他のアプローチncal)。
ビショップ

4

Perlを使用する1つの方法(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.

これはその後の月にどのように機能しますか。2月の週は再び1から開始するのではなく、5月6日から開始します。3月は9/10から開始します。
ニキルマレー

cal 02 2012、これは失敗しますか??
ニキルマレー

@Nikhil:どういう意味かわかりません。もっと詳しく説明していただけますか?スクリプトは失敗しcal 02 2012ますか?私のテストではうまくいったようです。
ビレイ

@ニヒル:ああ、わかった。質問を誤解しました。これは絶対的な週番号を意味し、各月に相対的ではありません。間もなく間違った答えを削除します。
ビレイ

1
cool ..答えを削除しないでください。参照用に保管してください。
ニキルマレー

1

slm、gcalによる回答についてコメントするのに十分な担当者がいませんがいない場合はを使用してMac OSにインストールできますbrew install gcal

(私は最初にここで答えを見つけ、次にこの答えを別の質問に見つけましたが、unixの答えにはMacにインストールするのに必要なすべての情報が欠けていました。)


0

これはコードが短く、今月以外の日付でも問題なく動作する私のソリューションです。米国の人々には申し訳ありませんが、これはISO形式を使用しています。つまり、週の最初の曜日は月曜日です。これは、calの-mオプションとdateの%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で「テキストから列へ」を実行するだけです。そしてもう一度、「固定」オプションを使用して、最初の列で「列へのテキスト」を実行します。このカレンダーの利点(水平方向との比較)は、自動フィルター(Alt + dff)を使用して週のみを検索できることです。

#!/ usr / bin / ksh
y = 2017
セット-team1 Petars Justas Richard Jukka Jesper
セット-team2 Modestas Timo Mats Andreas

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

echo "WN Month Mo Tu We Th Fr Sa Su; Team1; Team2"
ycal = `for m in 1 2 3 4 5 6 7 8 9 10 11 12
行う
IFS =
        cal -m $ m $ y | egrep -v "Mo | ^ $" |行の読み取り中
        行う
                echo $ line | grep -q $ y && mname = $ line || print $ mname $ line | sed 's /' $ y '//'
        やった
やった
IFS =
echo "$ ycal" |読み取り中にline2
行う
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 || i1 ++; \
                [$ i2 -eq $ {#team2 [@]}-1] && i2 = 0 || i2 ++にします。}
        printf '%2s%s;%s;%s \ n' $ wn $ line2 $ {team1 [$ i1]} $ {team2 [$ i2]}
        own = $ 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.