Di #! / Bin / bash. Perintah Unix untuk mendapatkan tanggal pertama dari hari kerja dalam sebulan

8

Saya mencari perintah Unix langsung untuk mendapatkan hari Minggu pertama bulan depan, Senin pertama bulan depan, Selasa pertama bulan depan, Rabu pertama bulan depan dll.

  1. Saya akan membutuhkannya dalam format tanggal yang lengkap (waktu tidak wajib)

  2. Saya bisa mendapatkan angka seperti 2, 3, 4 dll. Karena saya tidak ingin hanya angka, saya akan membutuhkannya dalam format tanggal (termasuk hari, bulan, tahun)

    $ NEXT_MONTH=`date +'%m %Y' -d 'next month'`
    $ echo $NEXT_MONTH
    04 2017
    
    $ NEXT_SUNDAY=`cal $NEXT_MONTH | awk 'NF==7 && !/^Su/{print $1;exit}'`
    $ echo $NEXT_SUNDAY
    2
  3. Saya perlu tanggal ini untuk mengirim pemberitahuan untuk grup email.

Mis: Saya bisa mendapatkan Sabtu pertama bulan depan seperti di bawah ini.

$ firstofmonth=$(date -d '+1 months' '+%Y%m01')
20170401

$ firstsaturday=$(date -d "$firstofmonth" '+%Y-%m')-$((7 - \
                $(date -d "$firstofmonth" '+%u')     ))    
2017-04-1
Hima
sumber

Jawaban:

11

Dalam ksh93:

$ printf '%(%F)T\n' 'next month, first Monday'
2017-04-03

bash, karena 4.2 sekarang mendukung a %(<format)Tdalam printfbuitinnya, tetapi bukan kemampuan untuk menguraikan ekspresi tanggal seperti ini.

Jika Anda harus menggunakan bashdan ingin menggunakannya %(<format>)T, Anda masih bisa melakukannya tanpa forking dengan sesuatu seperti:

printf -v code '%(
  t=$((%s + (12 - %-H) * 60 * 60))
  increment=$((8 - %u))
  current_month=%m)T' -1
eval "$code"
until
  t=$((t + increment * 24 * 60 * 60)) # next Monday around mid-day
  printf -v code '%(date=%F month=%m)T' "$t"
  eval "$code"
  [ "$month" != "$current_month" ] # until be get to next month
do
  increment=7 # the first increment is the number of days
              # til Monday. Next increments are just a week.
done
echo "$date"
Stéphane Chazelas
sumber
#! / bin / bash. Saya mendapatkan kesalahan di bawah ini di bash $ printf '% (% F) T \ n' 'bulan depan, Senin pertama -bash: printf: `(': karakter format tidak valid
Hima
1
@ Himima, saya memang mengatakan dalam ksh93 . bashadalah klon ksh yang belum selesai (dengan beberapa fitur (t) csh dan zsh dan bahkan beberapa miliknya sendiri). Versi terbaru bashtelah menambahkan dukungan untuk printf '%(format)T'dari ksh93, tetapi bukan kemampuan untuk menguraikan spesifikasi tanggal semacam ini. Ganti bang-bang Anda dengan #! /path/to/ksh93 -.
Stéphane Chazelas
" bashAdalah klon ksh yang belum selesai" - Saya selalu merasa seperti itu.
Tim Kennedy
@Stephene, saya mencoba dengan perintah di bawah ini untuk mendapatkan bulan depan sabtu lalu $ kal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 28 Ini menampilkan angka 28, tapi saya sedang mencari tanggal lengkap 04/28/2017, tl saran jika mungkin dengan itu.
Hima
9

Dengan asumsi GNU date(untuk itu -dAnda menggunakan diri Anda sendiri), dan zshshell-like untuk {1..7}:

$ for i in {1..7} ; do \
    LC_ALL=C date '+%Y-%m-%d %a' -d "$(date +%Y%m0${i}) next month" ; \
  done | awk '/Mon/ {print $1}'
2017-04-03

Ganti awk Mondengan apa pun hari kerja yang diperlukan (gunakan LC_ALL=Cuntuk mendapatkan nama bulan bahasa Inggris terlepas dari lokal pengguna). Juga, mungkin lebih baik untuk menyimpan ini ke dalam variabel jika Anda akan meminta kembali untuk setiap hari dalam seminggu:

$ days=$(for i in {1..7} ; do \
           LC_ALL=C date '+%Y-%m-%d %a' -d "$(date +%Y%m0${i}) next month" ; \
         done)

$ for i in Mon Tue Wed Thu Fri Sat Sun ; do \
    echo "${days}" | awk "/${i}/"'{print $1}' ; \
  done
2017-04-03
2017-04-04
2017-04-05
2017-04-06
2017-04-07
2017-04-01
2017-04-02
parkamark
sumber
Dalam bash juga, kode ini mengembalikan bulan depan pertama, Senin, Senin, Rabu, Jumat, Sabtu. Terima kasih. Saya pikir, saya dapat memodifikasi perintah ini untuk mendapatkan bulan depan Sun, Senin, Rabu dll. Biarkan saya coba ini.
Hima
Hai, saya mencoba perintah di bawah ini untuk mendapatkan bulan depan Sabtu lalu $ kal 04 2017 | awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 Ini menampilkan angka 28, tapi saya sedang mencari tanggal lengkap seperti 28/04/2017, tlg sarankan jika memungkinkan.
Hima
"untuk saya di {1..7}; lakukan tanggal '+% Y-% m-% d% a' -d" $ (tanggal +% Y% m01 -d '2 bulan') $ {i} hari yang lalu "; done | awk '/ Sat / {print $ 1}'" - ini akan menghasilkan 2017-04-29, yang merupakan hari Sabtu terakhir di bulan berikutnya. Kode ini berjalan 2 bulan ke depan, ke hari pertama bulan itu, dan kemudian kembali 1-7 hari untuk mendapatkan data hari 7 hari terakhir untuk bulan sebelumnya. Saya pribadi akan menghindari menggunakan cal karena saya telah mencoba contoh-contoh lain di sini dan tidak ada yang bekerja sama sekali pada versi saya (CentOS 6).
parkamark
2

PHP sebenarnya memudahkan penguraian tanggal dengan input tekstual, jika tersedia di sistem Anda.

Contoh:

bash-[522]$ php -qr 'date_default_timezone_set("UTC"); echo date("d-m-Y\n", strtotime("first monday of next month"));'
03-04-2017

Saya memiliki fungsi ini di .bashrc saya:

get_date ()
{
    text="$*";
    php -qr "date_default_timezone_set(\"UTC\"); echo date(\"d-m-Y\n\", strtotime(\"$text\"));"
}

Yang bisa saya gunakan sebagai:

bash-[523]$ get_date first monday of next month
03-04-2017

Edit opsi Menambahkan untuk digunakancal

Hampir setiap sistem yang dimiliki bashakan memiliki cal. Program kalender. Anda bisa mendapatkan daftar tanggal untuk pertama setiap hari minggu dengan menjalankan kombinasi cal, datedan awk, sebagai berikut:

 cal -hN $(date -d 'next month' +%b' '%Y) | grep -v $(date -d 'next month' +%b) | awk -v date=$(date -d 'next month' +%Y-%m-) '{ printf "%s: "date"%02i\n", $1, $2; }'

Yang akan memberi Anda output berikut:

Su: 2017-04-02
Mo: 2017-04-03
Tu: 2017-04-04
We: 2017-04-05
Th: 2017-04-06
Fr: 2017-04-07
Sa: 2017-04-01

Ubah $2ke $NFdalam pernyataan awk untuk mendapatkan tanggal kemunculan terakhir setiap hari dalam sebulan.

Tim Kennedy
sumber
Ini tidak bekerja di bash, $ php -qr 'date_default_timezone_set ("UTC"); tanggal gema ("dmY \ n", strtotime ("Senin pertama bulan berikutnya")); ' -bash: php: perintah tidak ditemukan. tolong beri tahu saya cara menyelesaikannya dengan bash juga. dan juga, perintah untuk mendapatkan bulan depan Sun lalu melalui Sat. Saya sudah mencobanya, beberapa cara melempar kesalahan. terima kasih .. !!
Hima
Berarti Anda belum phpmenginstal. Saya telah diperbarui dengan contoh yang menggunakan cal, datedan awkperintah.
Tim Kennedy
Saya mencoba perintah ini dan melempar kesalahan. Terima kasih.!! $ cal -hN $ (tanggal -d 'bulan depan' +% b ''% Y) | grep -v $ (tanggal -d 'bulan depan' +% b) | awk -v date = $ (tanggal -d 'bulan depan' +% Y-% m-) '{printf "% s:" date "% 02i \ n", $ 1, $ 2; } 'cal: opsi tidak valid - h penggunaan: cal [-13smjyV] [[bulan] tahun]
Hima